/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/Account.cpp
Line
Count
Source
1
//
2
// Created by Anh NPH on 28/09/2023.
3
//
4
5
#include "Account.h"
6
#include <cryptopp/xed25519.h>
7
#include <cryptopp/osrng.h>
8
#include "../HDWallet/Utils/Utils.h"
9
#include <cryptopp/cryptlib.h>
10
#include "AuthenticationKey.h"
11
12
namespace Aptos::Accounts
13
{
14
15
    Account::Account()
16
4
    {
17
4
        CryptoPP::AutoSeededRandomPool rng;
18
4
        CryptoPP::ed25519PrivateKey privateKey;
19
4
        privateKey.GenerateRandom(rng, CryptoPP::g_nullNameValuePairs);
20
4
        CryptoPP::ed25519PublicKey publicKey;
21
4
        privateKey.MakePublicKey(publicKey);
22
4
        CryptoPP::SecByteBlock privateKeyBytes(privateKey.GetPrivateKeyBytePtr(), Utils::Ed25519PrivateKeySeedSizeInBytes);
23
4
        CryptoPP::SecByteBlock publicKeyBytes(publicKey.GetPublicKeyBytePtr(), Utils::Ed25519PublicKeySizeInBytes);
24
4
        m_privateKey = std::make_shared<PrivateKey>(privateKeyBytes);
25
4
        m_publicKey = std::make_shared<PublicKey>(publicKeyBytes);
26
4
        m_accountAddress = std::make_shared<AccountAddress>(AccountAddress::FromKey(publicKeyBytes));
27
4
    }
28
29
    Account::Account(std::string privateKeyStr, std::string publicKeyStr)
30
1
    {
31
1
        m_privateKey = std::make_shared<PrivateKey>(privateKeyStr);
32
1
        m_publicKey = std::make_shared<PublicKey>(publicKeyStr);
33
1
        m_accountAddress = std::make_shared<AccountAddress>(AccountAddress::FromKey(*m_publicKey));
34
1
    }
35
36
    Account::Account(const CryptoPP::SecByteBlock &privateKeyBytes, const CryptoPP::SecByteBlock &publicKeyBytes)
37
8
    {
38
8
        m_privateKey = std::make_shared<PrivateKey>(privateKeyBytes);
39
8
        m_publicKey = std::make_shared<PublicKey>(publicKeyBytes);
40
8
        m_accountAddress = std::make_shared<AccountAddress>(AccountAddress::FromKey(*m_publicKey));
41
8
    }
42
43
    Account Account::LoadKey(std::string privateKeyHex)
44
1
    {
45
1
        PrivateKey privateKey(privateKeyHex);
46
1
        auto publicKey = privateKey.GetPublicKey();
47
1
        return Account(privateKey.ToString(), publicKey.ToString());
48
1
    }
49
50
    std::string Account::AuthKey()
51
1
    {
52
1
        auto authkey = AuthenticationKey::FromEd25519PublicKey(m_publicKey->KeyBytes());
53
1
        return authkey.DerivedAddress();
54
1
    }
55
56
    bool Account::Verify(const CryptoPP::SecByteBlock &message, Signature signature)
57
2
    {
58
2
        return m_publicKey->Verify(message, signature);
59
2
    }
60
61
    Signature Account::Sign(CryptoPP::SecByteBlock message)
62
3
    {
63
3
        return m_privateKey->Sign(message);
64
3
    }
65
66
    std::shared_ptr<PrivateKey> Account::getPrivateKey() const
67
3
    {
68
3
        return m_privateKey;
69
3
    }
70
71
    std::shared_ptr<PublicKey> Account::getPublicKey() const
72
3
    {
73
3
        return m_publicKey;
74
3
    }
75
76
    std::shared_ptr<AccountAddress> Account::getAccountAddress() const
77
2
    {
78
2
        return m_accountAddress;
79
2
    }
80
81
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/AccountAddress.cpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Created by Anh NPH on 28/09/2023.
3
//
4
5
#include <cryptopp/hex.h>
6
#include <cryptopp/sha.h>
7
#include "AccountAddress.h"
8
#include "../HDWallet/Utils/Utils.h"
9
#include <cryptopp/sha3.h>
10
#include <sstream>
11
#include <iomanip>
12
namespace Aptos::Accounts
13
{
14
    CryptoPP::SecByteBlock AccountAddress::addressBytes() const
15
4
    {
16
4
        return _addressBytes;
17
4
    }
18
19
    AccountAddress::AccountAddress(const CryptoPP::SecByteBlock &addressBytes)
20
136
    {
21
136
        if (addressBytes.size() != Length)
22
0
        {
23
0
            throw std::invalid_argument("Invalid address length.");
24
0
        }
25
136
        _addressBytes = addressBytes;
26
136
    }
27
28
    std::string AccountAddress::ToString() const
29
73
    {
30
73
        std::ostringstream addressHexStream;
31
73
        for (const auto &b : _addressBytes)
32
2.33k
        {
33
2.33k
            addressHexStream << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(b);
34
2.33k
        }
35
36
73
        std::string addressHex = addressHexStream.str();
37
38
73
        if (IsSpecial())
39
45
        {
40
45
            addressHex.erase(0, addressHex.find_first_not_of('0'));
41
45
            if (addressHex.empty())
42
1
            {
43
1
                addressHex = "0";
44
1
            }
45
45
        }
46
47
73
        return "0x" + addressHex;
48
73
    }
49
50
    bool AccountAddress::IsSpecial() const
51
73
    {
52
73
        bool allZeros = std::all_of(_addressBytes.begin(), _addressBytes.end() - 1, [](int i)
53
1.51k
                                    { return i == 0; });
54
73
        return allZeros && (_addressBytes[_addressBytes.size() - 1] < 0b10000);
55
73
    }
56
57
    AccountAddress AccountAddress::FromHex(std::string address)
58
100
    {
59
100
        if (address.empty())
60
0
        {
61
0
            throw std::invalid_argument("Address string is empty.");
62
0
        }
63
64
100
        std::string addr = address;
65
100
        if (addr.length() == 1)
66
1
        {
67
1
            addr = "0x" + addr;
68
1
        }
69
70
100
        if (addr.substr(0, 2) == "0x")
71
85
        {
72
85
            addr = addr.substr(2);
73
85
        }
74
100
        size_t expectedLength = AccountAddress::Length * 2;
75
76
100
        if (addr.length() < expectedLength)
77
85
        {
78
85
            std::string pad(expectedLength - addr.length(), '0');
79
85
            addr = pad + addr;
80
85
        }
81
100
        std::vector<uint8_t> byteArray;
82
3.30k
        for (size_t i = 0; i < addr.length(); i += 2)
83
3.20k
        {
84
3.20k
            std::string byteStr = addr.substr(i, 2);
85
3.20k
            uint8_t byte = static_cast<uint8_t>(std::stoul(byteStr, nullptr, 16));
86
3.20k
            byteArray.push_back(byte);
87
3.20k
        }
88
89
100
        return AccountAddress(Utils::ByteVectorToSecBlock(byteArray));
90
100
    }
91
92
    AccountAddress AccountAddress::FromKey(const CryptoPP::SecByteBlock &publicKey)
93
18
    {
94
18
        CryptoPP::SecByteBlock addressBytes{Utils::Ed25519PublicKeySizeInBytes + 1}; // +1 to contain signature scheme byte
95
18
        std::copy_n(publicKey.begin(), Utils::Ed25519PublicKeySizeInBytes, addressBytes.begin());
96
18
        CryptoPP::byte sigScheme = 0x00;                                   // signature scheme byte
97
18
        addressBytes[Utils::Ed25519PublicKeySizeInBytes] = sigScheme;      // Append signature scheme byte to the end
98
18
        CryptoPP::SecByteBlock result{Utils::Ed25519PublicKeySizeInBytes}; // Result hash must be 32 bytes
99
18
        CryptoPP::SHA3_256 sha3;
100
18
        sha3.Update(addressBytes.data(), addressBytes.size());
101
18
        sha3.Final(result);
102
18
        return AccountAddress(result);
103
18
    }
104
105
    AccountAddress AccountAddress::FromKey(const PublicKey &publicKey)
106
12
    {
107
12
        return AccountAddress::FromKey(publicKey.KeyBytes());
108
12
    }
109
110
    void AccountAddress::Serialize(Serialization &serializer) const
111
105
    {
112
105
        serializer.SerializeFixedBytes(Utils::SecBlockToByteVector(_addressBytes));
113
105
    }
114
115
    size_t AccountAddress::GetHashCode()
116
2
    {
117
2
        return ISerializable::GetHashCode();
118
2
    }
119
120
    TypeTag AccountAddress::Variant() const
121
2
    {
122
2
        return TypeTag::ACCOUNT_ADDRESS;
123
2
    }
124
125
    std::shared_ptr<ISerializableTag> AccountAddress::Deserialize(Deserialization &deserializer)
126
13
    {
127
13
        CryptoPP::SecByteBlock addressBytes = Utils::ByteVectorToSecBlock(deserializer.FixedBytes(AccountAddress::Length));
128
13
        return std::make_shared<AccountAddress>(addressBytes);
129
13
    }
130
131
    bool operator==(const AccountAddress &lhs, const AccountAddress &rhs)
132
25
    {
133
25
        return lhs.ToString() == rhs.ToString();
134
25
    }
135
136
    AccountAddress AccountAddress::ForNamedObject(const AccountAddress &creator, const CryptoPP::SecByteBlock &seed)
137
3
    {
138
        // Create a SHA3-256 hash object
139
3
        CryptoPP::SHA3_256 sha3;
140
141
        // Concatenate the creator's address, seed, and AuthKeyScheme value
142
3
        CryptoPP::SecByteBlock data;
143
3
        data.Append(creator.addressBytes());
144
3
        data.Append(seed);
145
3
        data.Append(1, AuthKeyScheme::DeriveObjectAddressFromSeed);
146
147
        // Calculate the hash
148
3
        CryptoPP::SecByteBlock result(Utils::Ed25519PublicKeySizeInBytes);
149
3
        sha3.Update(data.data(), data.size());
150
3
        sha3.Final(result);
151
152
3
        return AccountAddress(result);
153
3
    }
154
155
    AccountAddress AccountAddress::ForNamedToken(const AccountAddress &creator, const std::string &collectionName, const std::string &tokenName)
156
1
    {
157
1
        std::string combined = collectionName + "::" + tokenName;
158
1
        return AccountAddress::ForNamedObject(creator, Utils::StringToSecByteBlock(combined));
159
1
    }
160
161
    AccountAddress AccountAddress::ForNamedCollection(AccountAddress creator, std::string collectionName)
162
1
    {
163
1
        return AccountAddress::ForNamedObject(creator, Utils::StringToSecByteBlock(collectionName));
164
1
    }
165
166
    AccountAddress AccountAddress::ForResourceAccount(AccountAddress creator, const CryptoPP::SecByteBlock &seed)
167
1
    {
168
1
        CryptoPP::SHA3_256 sha3;
169
170
1
        CryptoPP::SecByteBlock data;
171
1
        data.Append(creator.addressBytes());
172
1
        data.Append(seed);
173
1
        data.Append(1, AuthKeyScheme::DeriveResourceAccountAddress);
174
175
        // Calculate the hash
176
1
        CryptoPP::SecByteBlock result(Utils::Ed25519PublicKeySizeInBytes);
177
1
        sha3.Update(data.data(), data.size());
178
1
        sha3.Final(result);
179
180
1
        return AccountAddress(result);
181
1
    }
182
183
    AccountAddress AccountAddress::FromMultiEd25519(MultiPublicKey keys)
184
1
    {
185
1
        CryptoPP::SHA3_256 sha3;
186
1
        CryptoPP::SecByteBlock result(Utils::Ed25519PublicKeySizeInBytes);
187
188
1
        std::vector<uint8_t> keyBytes = keys.ToBytes();
189
190
        // Calculate the hash
191
1
        CryptoPP::SecByteBlock data;
192
1
        data.Append(Utils::ByteVectorToSecBlock(keyBytes));
193
1
        data.Append(1, AuthKeyScheme::MultiEd25519);
194
195
1
        sha3.Update(data.data(), data.size());
196
1
        sha3.Final(result);
197
1
        return AccountAddress(result);
198
1
    }
199
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/AuthenticationKey.cpp
Line
Count
Source
1
//
2
// Created by Anh NPH on 28/09/2023.
3
//
4
5
#include "AuthenticationKey.h"
6
#include <cryptopp/hex.h>
7
#include <cryptopp/sha3.h>
8
#include <iomanip>
9
namespace Aptos::Accounts
10
{
11
    AuthenticationKey::AuthenticationKey(const CryptoPP::SecByteBlock &bytes)
12
3
    {
13
3
        if (bytes.size() != LENGTH)
14
1
            throw std::invalid_argument("Byte array must be " + std::to_string(LENGTH) + " bytes");
15
2
        _bytes = bytes;
16
2
    }
17
18
    AuthenticationKey AuthenticationKey::FromMultiEd25519PublicKey(Aptos::Accounts::Types::MultiEd25519PublicKey publicKey)
19
1
    {
20
1
        CryptoPP::SHA3_256 sha3;
21
1
        CryptoPP::SecByteBlock pubKeyBytes = publicKey.ToBytes();
22
1
        CryptoPP::SecByteBlock bytes;
23
1
        bytes.resize(pubKeyBytes.size() + 1);
24
1
        std::copy(pubKeyBytes.begin(), pubKeyBytes.end(), bytes.begin());
25
1
        bytes[pubKeyBytes.size()] = AuthenticationKey::MULTI_ED25519_SCHEME;
26
1
        sha3.Update(bytes.data(), bytes.size());
27
1
        CryptoPP::SecByteBlock result;
28
1
        result.resize(CryptoPP::ed25519PublicKey::PUBLIC_KEYLENGTH);
29
1
        sha3.Final(result.data());
30
1
        return AuthenticationKey(result);
31
1
    }
32
33
    AuthenticationKey AuthenticationKey::FromEd25519PublicKey(const CryptoPP::SecByteBlock &publicKey)
34
1
    {
35
1
        CryptoPP::SHA3_256 sha3;
36
1
        CryptoPP::SecByteBlock bytes;
37
1
        bytes.resize(CryptoPP::ed25519PublicKey::PUBLIC_KEYLENGTH + 1);
38
1
        std::copy(publicKey.begin(), publicKey.end(), bytes.begin());
39
1
        bytes[CryptoPP::ed25519PublicKey::PUBLIC_KEYLENGTH] = AuthenticationKey::ED25519_SCHEME;
40
1
        sha3.Update(bytes.data(), bytes.size());
41
1
        CryptoPP::SecByteBlock result;
42
1
        result.resize(CryptoPP::ed25519PublicKey::PUBLIC_KEYLENGTH);
43
1
        sha3.Final(result.data());
44
1
        return AuthenticationKey(result);
45
1
    }
46
47
    std::string AuthenticationKey::DerivedAddress()
48
2
    {
49
2
        std::ostringstream ss;
50
2
        ss << std::hex;
51
52
2
        for (const auto &byte : _bytes)
53
64
        {
54
64
            ss << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
55
64
        }
56
57
2
        return "0x" + ss.str();
58
2
    }
59
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/Ed25519Bip32.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "Ed25519Bip32.h"
2
#include "../HDWallet/Utils/Utils.h"
3
#include <boost/regex.hpp>
4
#include <boost/range/adaptors.hpp>
5
#include <boost/algorithm/string.hpp>
6
namespace Aptos::Accounts
7
{
8
    const std::string Ed25519Bip32::Curve = "ed25519 seed";
9
    const uint32_t Ed25519Bip32::HardenedOffset = 0x80000000;
10
11
    std::pair<CryptoPP::SecByteBlock, CryptoPP::SecByteBlock> Ed25519Bip32::DerivePath(const std::string &path)
12
4
    {
13
4
        if (!IsValidPath(path))
14
1
        {
15
1
            throw std::invalid_argument("Invalid derivation path");
16
1
        }
17
18
3
        std::istringstream stream(path);
19
3
        std::string segment;
20
3
        getline(stream, segment, '/'); // Read and discard the "m"
21
22
3
        std::vector<uint32_t> segments;
23
18
        while (getline(stream, segment, '/'))
24
15
        {
25
15
            uint32_t index = std::stoul(segment);
26
15
            if (segment.back() == '\'')
27
15
            {
28
15
                index += HardenedOffset;
29
15
            }
30
15
            segments.push_back(index);
31
15
        }
32
33
3
        std::pair<CryptoPP::SecByteBlock, CryptoPP::SecByteBlock> result = std::make_pair(_masterKey, _chainCode);
34
3
        for (uint32_t index : segments)
35
15
        {
36
15
            result = GetChildKeyDerivation(result.first, result.second, index);
37
15
        }
38
39
3
        return result;
40
4
    }
41
42
    bool Ed25519Bip32::IsValidPath(const std::string &path)
43
5
    {
44
5
        boost::regex regex("^m(\\/[0-9]+')+$");
45
46
5
        if (!boost::regex_match(path, regex))
47
2
            return false;
48
49
3
        std::vector<std::string> parts;
50
3
        boost::split(parts, path, boost::is_any_of("/"));
51
52
3
        if (parts.size() < 2)
53
0
            return false;
54
55
3
        parts.erase(parts.begin()); // Remove the "m" part
56
3
        for (auto &part : parts)
57
15
        {
58
15
            boost::replace_all(part, "'", "");
59
15
            if (!boost::algorithm::all(part, boost::algorithm::is_digit()))
60
0
                return false;
61
15
        }
62
63
3
        return true;
64
3
    }
65
66
    std::pair<CryptoPP::SecByteBlock, CryptoPP::SecByteBlock> Ed25519Bip32::HmacSha512(const CryptoPP::SecByteBlock &keyBuffer, const CryptoPP::SecByteBlock &data)
67
19
    {
68
19
        CryptoPP::HMAC<CryptoPP::SHA512> hmac(keyBuffer, keyBuffer.size());
69
19
        hmac.Update(data, data.size());
70
19
        CryptoPP::SecByteBlock i(64);
71
19
        hmac.Final(i);
72
19
        CryptoPP::SecByteBlock il(32);
73
19
        il.Assign(i.data(), 32);
74
19
        CryptoPP::SecByteBlock ir(32);
75
19
        ir.Assign(i.data() + 32, 32);
76
19
        return std::make_pair(il, ir);
77
19
    }
78
79
    Ed25519Bip32::Ed25519Bip32(const std::vector<uint8_t> &seed)
80
4
    {
81
4
        _masterKey.resize(32);
82
4
        _chainCode.resize(32);
83
84
4
        std::tie(_masterKey, _chainCode) = GetMasterKeyFromSeed(CryptoPP::SecByteBlock(seed.data(), seed.size()));
85
4
    }
86
87
    std::pair<CryptoPP::SecByteBlock, CryptoPP::SecByteBlock> Ed25519Bip32::GetMasterKeyFromSeed(const CryptoPP::SecByteBlock &seed)
88
4
    {
89
4
        return HmacSha512(Utils::StringToSecByteBlock(Curve), seed);
90
4
    }
91
92
    std::pair<CryptoPP::SecByteBlock, CryptoPP::SecByteBlock> Ed25519Bip32::GetChildKeyDerivation(const CryptoPP::SecByteBlock &key,
93
                                                                                                  const CryptoPP::SecByteBlock &chainCode,
94
                                                                                                  uint32_t index)
95
15
    {
96
15
        std::vector<uint8_t> buffer;
97
15
        buffer.push_back(0);
98
15
        buffer.insert(buffer.end(), key.begin(), key.end());
99
        // buffer.insert(buffer.end(), reinterpret_cast<uint8_t*>(&index), reinterpret_cast<uint8_t*>(&index) + sizeof(index));
100
        // Convert index to big-endian
101
15
        index = htonl(index);
102
15
        uint8_t *indexPtr = reinterpret_cast<uint8_t *>(&index);
103
104
        // Insert index into buffer
105
15
        buffer.insert(buffer.end(), indexPtr, indexPtr + sizeof(index));
106
107
15
        return HmacSha512(chainCode, CryptoPP::SecByteBlock(buffer.data(), buffer.size()));
108
15
    }
109
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/PrivateKey.cpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Created by Anh NPH on 26/09/2023.
3
//
4
5
#include "PrivateKey.h"
6
#include "cryptopp/hex.h"
7
#include "cryptopp/sha.h"
8
#include "cryptopp/secblock.h"
9
#include "cryptopp/xed25519.h"
10
#include "cryptopp/osrng.h"
11
#include <iostream>
12
#include "../HDWallet/Utils/Utils.h"
13
14
namespace Aptos::Accounts
15
{
16
    std::string PrivateKey::Key()
17
11
    {
18
11
        if (_key.empty() && !_keyBytes.empty())
19
6
        {
20
6
            _key = "0x";
21
6
            CryptoPP::StringSource ss(_keyBytes.data(), _keyBytes.size(), true,
22
6
                                      new CryptoPP::HexEncoder(
23
6
                                          new CryptoPP::StringSink(_key),
24
6
                                          false) // HexDecoder
25
6
            );                                   // StringSource
26
6
        }
27
11
        return _key;
28
11
    }
29
30
    void PrivateKey::Key(std::string key)
31
1
    {
32
1
        _key = key;
33
1
    }
34
35
    CryptoPP::SecByteBlock PrivateKey::KeyBytes()
36
21
    {
37
21
        if (_keyBytes.empty() && !_key.empty())
38
14
        {
39
14
            std::string key = _key;
40
14
            if (key.substr(0, 2) == "0x")
41
4
            {
42
4
                key = key.substr(2);
43
4
            }
44
14
            CryptoPP::HexDecoder decoder;
45
14
            decoder.Put((CryptoPP::byte *)key.data(), key.size());
46
14
            decoder.MessageEnd();
47
14
            size_t size = decoder.MaxRetrievable();
48
14
            if (size && size <= SIZE_MAX)
49
14
            {
50
14
                _keyBytes.resize(size);
51
14
                decoder.Get((CryptoPP::byte *)&_keyBytes[0], _keyBytes.size());
52
14
                GenerateExtendedKey();
53
14
            }
54
14
        }
55
21
        return _keyBytes;
56
21
    }
57
58
    void PrivateKey::KeyBytes(CryptoPP::SecByteBlock value)
59
3
    {
60
3
        if (value.empty())
61
0
            throw std::invalid_argument("PublicKey cannot be null.");
62
3
        if (value.size() != KeyLength)
63
1
            throw std::invalid_argument("Invalid key length.");
64
2
        _keyBytes = value;
65
2
    }
66
67
    PrivateKey::PrivateKey(std::string key)
68
24
    {
69
24
        if (key.empty())
70
1
            throw std::invalid_argument("Key cannot be null.");
71
23
        if (!Utils::IsValidAddress(key))
72
1
            throw std::invalid_argument("Invalid key.");
73
22
        _key = key;
74
22
    }
Unexecuted instantiation: _ZN5Aptos8Accounts10PrivateKeyC2ENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE
_ZN5Aptos8Accounts10PrivateKeyC1ENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE
Line
Count
Source
68
24
    {
69
24
        if (key.empty())
70
1
            throw std::invalid_argument("Key cannot be null.");
71
23
        if (!Utils::IsValidAddress(key))
72
1
            throw std::invalid_argument("Invalid key.");
73
22
        _key = key;
74
22
    }
75
76
    PrivateKey::PrivateKey(std::array<CryptoPP::byte, KeyLength> privateKey)
77
0
    {
78
        // todo
79
0
    }
Unexecuted instantiation: _ZN5Aptos8Accounts10PrivateKeyC2ENSt3__15arrayIhLm32EEE
Unexecuted instantiation: _ZN5Aptos8Accounts10PrivateKeyC1ENSt3__15arrayIhLm32EEE
80
81
    PrivateKey PrivateKey::FromHex(std::string key)
82
15
    {
83
15
        return PrivateKey(key);
84
15
    }
85
86
    PublicKey PrivateKey::GetPublicKey()
87
14
    {
88
14
        if (_keyBytes.empty())
89
10
        {
90
10
            KeyBytes();
91
10
        }
92
14
        CryptoPP::SecByteBlock publicKeyBytes;
93
14
        publicKeyBytes.resize(CryptoPP::ed25519PublicKey::PUBLIC_KEYLENGTH);
94
14
        this->SecretToPublicKey(publicKeyBytes.data(), _keyBytes.data());
95
14
        return PublicKey(publicKeyBytes);
96
14
    }
97
98
    bool PrivateKey::operator!=(const PrivateKey &rhs) const
99
1
    {
100
1
        return !Equals(rhs);
101
1
    }
102
103
    Signature PrivateKey::Sign(CryptoPP::SecByteBlock message)
104
10
    {
105
        // CryptoPP::AutoSeededRandomPool prng;
106
10
        if (_keyBytes.empty())
107
1
        {
108
1
            KeyBytes();
109
1
        }
110
10
        CryptoPP::ed25519::Signer signer(_keyBytes.data());
111
10
        std::string signature;
112
10
        size_t siglen = signer.MaxSignatureLength();
113
10
        signature.resize(siglen);
114
10
        signer.SignMessage(CryptoPP::NullRNG(), message.data(), message.size(),
115
10
                           (CryptoPP::byte *)&signature[0]);
116
10
        signature.resize(siglen);
117
10
        CryptoPP::SecByteBlock signatureData;
118
10
        signatureData.resize(signature.size());
119
10
        std::copy(signature.begin(), signature.end(), signatureData.begin());
120
10
        return Signature(signatureData);
121
10
    }
122
123
    void PrivateKey::Serialize(Serialization &serializer)
124
2
    {
125
2
        if (_keyBytes.empty())
126
1
        {
127
1
            KeyBytes();
128
1
        }
129
2
        auto bytes = Utils::SecBlockToByteVector(_keyBytes);
130
2
        serializer.SerializeBytes(bytes);
131
2
    }
132
133
    bool PrivateKey::Equals(const PrivateKey &rhs) const
134
2
    {
135
2
        return _key == rhs._key;
136
2
    }
137
138
    int PrivateKey::GetHashCode() const
139
1
    {
140
1
         return std::hash<std::string>{}(_key);
141
1
    }
142
143
    std::string PrivateKey::ToString()
144
2
    {
145
2
        return Key();
146
2
    }
147
148
    PrivateKey PrivateKey::Random()
149
1
    {
150
1
        CryptoPP::SecByteBlock seed(KeyLength);
151
1
        CryptoPP::AutoSeededRandomPool rng;
152
1
        rng.GenerateBlock(seed.data(), seed.size());
153
1
        return PrivateKey(seed);
154
1
    }
155
156
    PrivateKey::PrivateKey(CryptoPP::SecByteBlock privateKey)
157
23
    {
158
23
        if (privateKey.empty())
159
0
            throw std::invalid_argument("PublicKey cannot be null.");
160
23
        if (privateKey.size() != KeyLength)
161
2
            throw std::invalid_argument("Invalid key length.");
162
21
        _keyBytes = privateKey;
163
21
    }
Unexecuted instantiation: _ZN5Aptos8Accounts10PrivateKeyC2EN8CryptoPP8SecBlockIhNS2_20AllocatorWithCleanupIhLb0EEEEE
_ZN5Aptos8Accounts10PrivateKeyC1EN8CryptoPP8SecBlockIhNS2_20AllocatorWithCleanupIhLb0EEEEE
Line
Count
Source
157
23
    {
158
23
        if (privateKey.empty())
159
0
            throw std::invalid_argument("PublicKey cannot be null.");
160
23
        if (privateKey.size() != KeyLength)
161
2
            throw std::invalid_argument("Invalid key length.");
162
21
        _keyBytes = privateKey;
163
21
    }
164
165
    bool PrivateKey::operator==(const PrivateKey &rhs) const
166
1
    {
167
1
        return Equals(rhs);
168
1
    }
169
170
    void PrivateKey::GenerateExtendedKey()
171
14
    {
172
173
14
        CryptoPP::SecByteBlock extendedKey(ExtendedKeyLength);
174
175
14
        CryptoPP::SHA512 sha;
176
14
        sha.CalculateDigest(extendedKey,
177
14
                            _keyBytes.data(), _keyBytes.size());
178
179
14
        _extendedKeyBytes.Assign(extendedKey.data(), extendedKey.size());
180
14
    }
181
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/PublicKey.cpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Created by Anh NPH on 25/09/2023.
3
//
4
5
#include "PublicKey.h"
6
#include "Signature.h"
7
#include "../HDWallet/Utils/Utils.h"
8
#include "cryptopp/hex.h"
9
#include "cryptopp/xed25519.h"
10
11
namespace Aptos::Accounts
12
{
13
    PublicKey::PublicKey(const CryptoPP::SecByteBlock &publicKey)
14
48
    {
15
48
        if (publicKey.empty())
16
1
        {
17
1
            throw std::invalid_argument("PublicKey cannot be null.");
18
1
        }
19
47
        if (publicKey.size() != KeyLength)
20
1
        {
21
1
            throw std::invalid_argument("Invalid key length.");
22
1
        }
23
46
        _keyBytes = publicKey;
24
46
    }
25
26
    PublicKey::PublicKey(std::string key)
27
18
    {
28
18
        if (!Utils::IsValidAddress(key))
29
1
        {
30
1
            throw std::invalid_argument("Invalid key.");
31
1
        }
32
17
        if (key.empty())
33
0
        {
34
0
            throw std::invalid_argument("Key cannot be null.");
35
0
        }
36
17
        if (key.substr(0, 2) == "0x")
37
17
        {
38
17
            key = key.substr(2);
39
17
        }
40
17
        CryptoPP::HexDecoder decoder;
41
17
        decoder.Put((CryptoPP::byte *)key.data(), key.size());
42
17
        decoder.MessageEnd();
43
17
        size_t size = decoder.MaxRetrievable();
44
17
        if (size && size <= SIZE_MAX)
45
17
        {
46
17
            _keyBytes.resize(size);
47
17
            decoder.Get((CryptoPP::byte *)&_keyBytes[0], _keyBytes.size());
48
17
        }
49
17
    }
50
51
    std::string PublicKey::Key() const
52
31
    {
53
31
        std::string key = "0x";
54
31
        CryptoPP::StringSource ss(_keyBytes.data(), _keyBytes.size(), true,
55
31
                                  new CryptoPP::HexEncoder(
56
31
                                      new CryptoPP::StringSink(key),
57
31
                                      false) // HexDecoder
58
31
        );                                   // StringSource
59
31
        return key;
60
31
    }
61
62
    void PublicKey::setKey(std::string key)
63
3
    {
64
3
        if (!Utils::IsValidAddress(key))
65
2
        {
66
2
            throw std::invalid_argument("Invalid key.");
67
2
        }
68
1
        if (key.empty())
69
0
        {
70
0
            throw std::invalid_argument("Key cannot be null.");
71
0
        }
72
1
        CryptoPP::HexDecoder decoder;
73
1
        decoder.Put((CryptoPP::byte *)key.data(), key.size());
74
1
        decoder.MessageEnd();
75
1
        size_t size = decoder.MaxRetrievable();
76
1
        if (size && size <= SIZE_MAX)
77
1
        {
78
1
            _keyBytes.resize(size);
79
1
            decoder.Get((CryptoPP::byte *)&_keyBytes[0], _keyBytes.size());
80
1
        }
81
1
    }
82
83
    CryptoPP::SecByteBlock PublicKey::KeyBytes() const
84
30
    {
85
30
        return _keyBytes;
86
30
    }
87
88
    void PublicKey::setKeyBytes(const CryptoPP::SecByteBlock &bytes)
89
3
    {
90
3
        if (bytes.empty())
91
1
        {
92
1
            throw std::invalid_argument("Key bytes cannot be null.");
93
1
        }
94
2
        if (bytes.size() != KeyLength)
95
1
        {
96
1
            throw std::invalid_argument("Invalid key length.");
97
1
        }
98
1
        _keyBytes = bytes;
99
1
    }
100
101
    bool PublicKey::Verify(const CryptoPP::SecByteBlock &message, const Signature &signature) const
102
10
    {
103
10
        CryptoPP::ed25519::Verifier verifier(_keyBytes);
104
10
        return verifier.VerifyMessage(message.data(), message.size(),
105
10
                                      signature.Data().data(), signature.Data().size());
106
10
    }
107
108
    bool PublicKey::IsOnCurve() const
109
1
    {
110
        // todo
111
1
        return false;
112
1
    }
113
114
    void PublicKey::Serialize(Serialization &serializer) const
115
13
    {
116
13
        std::vector<uint8_t> byteArray = Utils::SecBlockToByteVector(_keyBytes);
117
13
        serializer.SerializeBytes(byteArray);
118
13
    }
119
120
    std::shared_ptr<ISerializable> PublicKey::Deserialize(Deserialization &deserializer)
121
6
    {
122
6
        auto bytes = deserializer.ToBytes();
123
6
        CryptoPP::SecByteBlock keyBytes = Utils::ByteVectorToSecBlock(bytes);
124
6
        if (keyBytes.size() != KeyLength)
125
0
        {
126
0
            throw std::runtime_error("Length mismatch. Expected: " + std::to_string(KeyLength) + ", Actual: " + std::to_string(keyBytes.size()));
127
0
        }
128
6
        return std::make_shared<PublicKey>(keyBytes);
129
6
    }
130
131
    std::string PublicKey::ToString() const
132
2
    {
133
2
        return Key();
134
2
    }
135
136
    size_t PublicKey::GetHashCode() const
137
4
    {
138
4
        return std::hash<std::string>{}(Key());
139
4
    }
140
141
    bool PublicKey::Equals(const PublicKey &rhs) const
142
10
    {
143
10
        return Key() == rhs.Key();
144
10
    }
145
146
    bool PublicKey::operator==(const PublicKey &rhs) const
147
3
    {
148
3
        return Equals(rhs);
149
3
    }
150
151
    bool PublicKey::operator!=(const PublicKey &rhs) const
152
2
    {
153
2
        return !Equals(rhs);
154
2
    }
155
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/Signature.cpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Created by Anh NPH on 11/09/2023.
3
//
4
5
#include "Signature.h"
6
#include <stdexcept>
7
#include <sstream>
8
#include <cryptopp/hex.h>
9
#include <cryptopp/filters.h>
10
#include "../HDWallet/Utils/Utils.h"
11
#include <iostream>
12
#include <iomanip>
13
#include <sstream>
14
15
using namespace Aptos::BCS;
16
namespace Aptos::Accounts
17
{
18
    Signature::Signature(const CryptoPP::SecByteBlock &signature)
19
23
        : _signatureBytes(signature) {}
20
21
    bool Signature::Equals(const Signature &rhs) const
22
6
    {
23
6
        return _signatureBytes == rhs._signatureBytes;
24
6
    }
25
26
    CryptoPP::SecByteBlock Signature::Data() const
27
21
    {
28
21
        return _signatureBytes;
29
21
    }
30
31
    void Signature::Serialize(Serialization &serializer) const
32
13
    {
33
13
        auto bytes = Utils::SecBlockToByteVector(_signatureBytes);
34
13
        serializer.SerializeBytes(bytes);
35
13
    }
36
37
    std::shared_ptr<ISerializable> Signature::Deserialize(Deserialization &deserializer)
38
6
    {
39
6
        CryptoPP::SecByteBlock sigBytes = Utils::ByteVectorToSecBlock(deserializer.ToBytes());
40
6
        if (sigBytes.size() != SignatureLength)
41
0
        {
42
0
            throw std::runtime_error("Length mismatch");
43
0
        }
44
6
        return std::make_shared<Signature>(sigBytes);
45
6
    }
46
47
    bool Signature::operator==(const Signature &other) const
48
6
    {
49
6
        return ToString() == other.ToString();
50
6
    }
51
52
    bool Signature::operator!=(const Signature &other) const
53
0
    {
54
0
        return !(*this == other);
55
0
    }
56
57
    std::string Signature::ToString() const
58
12
    {
59
12
        std::ostringstream stream;
60
12
        for (auto byte : _signatureBytes)
61
768
        {
62
768
            stream << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
63
768
        }
64
65
12
        std::string _signature = "0x" + stream.str();
66
12
        return _signature;
67
12
    }
68
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/Types/MultiEd25519PublicKey.cpp
Line
Count
Source
1
#include <string>
2
#include "MultiEd25519PublicKey.h"
3
#include <cryptopp/xed25519.h>
4
#include "../../HDWallet/Utils/Utils.h"
5
6
namespace Aptos::Accounts::Types
7
{
8
    MultiEd25519PublicKey::MultiEd25519PublicKey(std::vector<PublicKey> PublicKeys, int threshold)
9
3
    {
10
3
        if (threshold > MAX_SIGNATURES_SUPPORTED)
11
1
            throw std::invalid_argument("Threshold cannot be larger than " + std::to_string(MAX_SIGNATURES_SUPPORTED));
12
13
2
        this->PublicKeys = PublicKeys;
14
2
        this->threshold = threshold;
15
2
    }
16
17
    CryptoPP::SecByteBlock MultiEd25519PublicKey::ToBytes()
18
1
    {
19
1
        size_t secBlockSize = (PublicKeys.size() * Utils::Ed25519PublicKeySizeInBytes) + 1;
20
1
        CryptoPP::SecByteBlock bytes(secBlockSize);
21
        //    for (int i = 0; i < PublicKeys.size(); i++) {
22
        //        bytes[i * Utils::Ed25519PublicKeySizeInBytes] = PublicKeys[i] ;
23
        //    }
24
        //    bytes[PublicKeys.size() * Utils::Ed25519PublicKeySizeInBytes] = static_cast<CryptoPP::byte>(threshold);
25
26
1
        return bytes;
27
1
    }
28
} // namespace Aptos
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/multipublickey.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "multipublickey.h"
2
#include "../HDWallet/Utils/Utils.h"
3
4
namespace Aptos::Accounts
5
{
6
    MultiPublicKey::MultiPublicKey(const std::vector<PublicKey> &keys, CryptoPP::byte threshold, bool checked)
7
3
    {
8
3
        if (checked)
9
3
        {
10
3
            if (!(MIN_KEYS <= keys.size() && keys.size() <= MAX_KEYS))
11
0
                throw std::invalid_argument("Must have between " + std::to_string(MIN_KEYS) + " and " + std::to_string(MAX_KEYS) + " keys.");
12
13
3
            if (!(MIN_THRESHOLD <= threshold && threshold < keys.size()))
14
0
                throw std::invalid_argument("Threshold must be between " + std::to_string(MIN_THRESHOLD) + " and " + std::to_string(keys.size()));
15
3
        }
16
17
3
        Keys = keys;
18
3
        Threshold = threshold;
19
3
    }
20
21
    std::vector<uint8_t> MultiPublicKey::ToBytes() const
22
4
    {
23
4
        CryptoPP::SecByteBlock concatenatedKeys;
24
4
        for (const PublicKey &key : Keys)
25
8
        {
26
8
            concatenatedKeys.Append(key.KeyBytes());
27
8
        }
28
4
        concatenatedKeys.Append(1, Threshold);
29
4
        return Utils::SecBlockToByteVector(concatenatedKeys);
30
4
    }
31
32
    MultiPublicKey MultiPublicKey::FromBytes(const std::vector<uint8_t> &keyBytes)
33
1
    {
34
1
        const int minKeys = MIN_KEYS;
35
1
        const int maxKeys = MAX_KEYS;
36
1
        const int minThreshold = MIN_THRESHOLD;
37
38
1
        int nSigners = keyBytes.size() / Utils::Ed25519PublicKeySizeInBytes;
39
1
        if (!(minKeys <= nSigners && nSigners <= maxKeys))
40
0
        {
41
0
            throw std::invalid_argument("Must have between " + std::to_string(minKeys) + " and " + std::to_string(maxKeys) + " keys.");
42
0
        }
43
1
        CryptoPP::byte threshold = keyBytes[keyBytes.size() - 1];
44
1
        if (!(minThreshold <= threshold && threshold <= nSigners))
45
0
        {
46
0
            throw std::invalid_argument("Threshold must be between " + std::to_string(minThreshold) + " and " + std::to_string(nSigners));
47
0
        }
48
1
        std::vector<PublicKey> keys;
49
3
        for (int i = 0; i < nSigners; i++)
50
2
        {
51
2
            int startByte = i * Utils::Ed25519PublicKeySizeInBytes;
52
2
            int endByte = (i + 1) * Utils::Ed25519PublicKeySizeInBytes;
53
2
            std::vector<uint8_t> tempKey(keyBytes.begin() + startByte, keyBytes.begin() + endByte);
54
2
            PublicKey publicKey(Utils::ByteVectorToSecBlock(tempKey));
55
2
            keys.push_back(publicKey);
56
2
        }
57
58
1
        return MultiPublicKey(keys, threshold);
59
1
    }
60
61
    void MultiPublicKey::Serialize(Serialization &serializer) const
62
2
    {
63
2
        auto bytes = this->ToBytes();
64
2
        serializer.SerializeBytes(bytes);
65
2
    }
66
67
    std::string MultiPublicKey::ToString() const
68
0
    {
69
0
        return std::to_string(this->Threshold) + "-of-" + std::to_string(this->Keys.size()) + " Multi-Ed25519 public key";
70
0
    }
71
72
    std::vector<PublicKey> MultiPublicKey::getKeys() const
73
1
    {
74
1
        return Keys;
75
1
    }
76
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Accounts/multisignature.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "multisignature.h"
2
#include "../HDWallet/Utils/Utils.h"
3
#if defined(__APPLE__)
4
#include <libkern/OSByteOrder.h>
5
6
1
#define htobe32(x) OSSwapHostToBigInt32(x)
7
#define be32toh(x) OSSwapBigToHostInt32(x)
8
#endif
9
10
namespace Aptos::Accounts
11
{
12
    MultiSignature::MultiSignature(const MultiPublicKey &PublicKeyMulti, const std::vector<std::pair<PublicKey, Signature>> &SignatureMap)
13
1
    {
14
1
        Signatures = std::vector<Signature>();
15
1
        int bitmap = 0;
16
1
        auto keys = PublicKeyMulti.getKeys();
17
1
        for (const auto &entry : SignatureMap)
18
1
        {
19
1
            this->Signatures.push_back(entry.second);
20
1
            int index = std::distance(keys.begin(), std::find(keys.begin(), keys.end(), entry.first));
21
1
            int shift = 31 - index;
22
1
            bitmap = bitmap | (1 << shift);
23
1
        }
24
25
1
        uint32_t uBitmap = htobe32(static_cast<uint32_t>(bitmap));
26
1
        this->Bitmap = std::vector<uint8_t>(reinterpret_cast<uint8_t *>(&uBitmap), reinterpret_cast<uint8_t *>(&uBitmap) + sizeof(uint32_t));
27
1
    }
28
29
    std::vector<uint8_t> MultiSignature::ToBytes() const
30
1
    {
31
1
        std::vector<uint8_t> concatenatedSignatures;
32
1
        for (const Signature &signature : Signatures)
33
1
        {
34
1
            std::vector<uint8_t> signatureBytes = Utils::SecBlockToByteVector(signature.Data());
35
1
            concatenatedSignatures.insert(std::end(concatenatedSignatures), std::begin(signatureBytes), std::end(signatureBytes));
36
1
        }
37
1
        concatenatedSignatures.insert(std::end(concatenatedSignatures), std::begin(Bitmap), std::end(Bitmap));
38
1
        return concatenatedSignatures;
39
1
    }
40
41
    void MultiSignature::Serialize(Serialization &serializer) const
42
1
    {
43
1
        std::vector<uint8_t> bytes = ToBytes();
44
1
        serializer.SerializeBytes(bytes);
45
1
    }
46
47
    std::string MultiSignature::ToString() const
48
0
    {
49
0
        return "MultiSignature";
50
0
    }
51
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/Authenticator.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "Authenticator.h"
2
#include "Sequence.h"
3
4
namespace Aptos::BCS
5
{
6
    Authenticator::Authenticator(const std::shared_ptr<IAuthenticator> &authenticator) : Variant(Authenticator::ED25519), m_authenticator(authenticator)
7
11
    {
8
11
        if (std::dynamic_pointer_cast<Ed25519Authenticator>(authenticator))
9
8
        {
10
8
            Variant = Authenticator::ED25519;
11
8
        }
12
3
        else if (std::dynamic_pointer_cast<MultiEd25519Authenticator>(authenticator))
13
0
        {
14
0
            Variant = Authenticator::MULTI_ED25519;
15
0
        }
16
3
        else if (std::dynamic_pointer_cast<MultiAgentAuthenticator>(authenticator))
17
3
        {
18
3
            Variant = Authenticator::MULTI_AGENT;
19
3
        }
20
0
        else
21
0
        {
22
0
            throw std::invalid_argument("Invalid type");
23
0
        }
24
11
    }
25
26
    Authenticator::VariantType Authenticator::GetVariant() const
27
4
    {
28
4
        return Variant;
29
4
    }
30
31
    std::shared_ptr<IAuthenticator> Authenticator::GetAuthenticator() const
32
5
    {
33
5
        return m_authenticator;
34
5
    }
35
36
    bool Authenticator::Verify(const CryptoPP::SecByteBlock &data)
37
7
    {
38
7
        return m_authenticator->Verify(data);
39
7
    }
40
41
    void Authenticator::Serialize(Serialization &serializer) const
42
14
    {
43
14
        serializer.SerializeU32AsUleb128(static_cast<uint32_t>(Variant));
44
14
        m_authenticator->Serialize(serializer);
45
14
    }
46
47
    std::shared_ptr<ISerializable> Authenticator::Deserialize(Deserialization &deserializer)
48
7
    {
49
7
        int variant = deserializer.DeserializeUleb128();
50
7
        std::shared_ptr<IAuthenticator> authenticator = nullptr;
51
52
7
        if (variant == Authenticator::ED25519)
53
5
        {
54
5
            authenticator = std::dynamic_pointer_cast<Ed25519Authenticator>(Ed25519Authenticator::Deserialize(deserializer));
55
5
        }
56
2
        else if (variant == Authenticator::MULTI_ED25519)
57
0
        {
58
0
            authenticator = std::dynamic_pointer_cast<MultiEd25519Authenticator>(MultiEd25519Authenticator::Deserialize(deserializer));
59
0
        }
60
2
        else if (variant == Authenticator::MULTI_AGENT)
61
2
        {
62
2
            authenticator = std::dynamic_pointer_cast<MultiAgentAuthenticator>(MultiAgentAuthenticator::Deserialize(deserializer));
63
2
        }
64
0
        else
65
0
        {
66
0
            throw std::runtime_error("Invalid type: " + std::to_string(variant));
67
0
        }
68
69
7
        return std::make_shared<Authenticator>(authenticator);
70
7
    }
71
72
    bool Authenticator::Equals(const Authenticator &other) const
73
7
    {
74
7
        bool vr = Variant == other.Variant;
75
7
        bool vl = false;
76
7
        if (vr)
77
7
        {
78
7
            if (Variant == Authenticator::ED25519)
79
5
            {
80
5
                vl = std::dynamic_pointer_cast<Ed25519Authenticator>(m_authenticator)->Equals(*(std::dynamic_pointer_cast<Ed25519Authenticator>(other.m_authenticator)));
81
5
            }
82
2
            else if (Variant == Authenticator::MULTI_ED25519)
83
0
            {
84
0
                vl = false /*std::dynamic_pointer_cast<MultiEd25519Authenticator>(m_authenticator)->Equals(
85
                            *(std::dynamic_pointer_cast<MultiEd25519Authenticator>(other.m_authenticator)))*/
86
0
                    ;
87
0
            }
88
2
            else if (Variant == Authenticator::MULTI_AGENT)
89
2
            {
90
2
                vl = std::dynamic_pointer_cast<MultiAgentAuthenticator>(m_authenticator)->Equals(*(std::dynamic_pointer_cast<MultiAgentAuthenticator>(other.m_authenticator)));
91
2
            }
92
0
            else
93
0
            {
94
0
                return false;
95
0
            }
96
7
            return vr && vl;
97
7
        }
98
0
        return false;
99
7
    }
100
101
    int Authenticator::GetHashCode() const
102
0
    {
103
0
        return m_authenticator->GetHashCode();
104
0
    }
105
106
    std::string Authenticator::ToString() const
107
0
    {
108
0
        return m_authenticator->ToString();
109
0
    }
110
111
    Ed25519Authenticator::Ed25519Authenticator(PublicKey publicKey, Signature signature)
112
8
        : m_publicKey(publicKey), m_signature(signature) {}
113
114
    bool Ed25519Authenticator::Verify(const CryptoPP::SecByteBlock &data)
115
5
    {
116
5
        return m_publicKey.Verify(data, m_signature);
117
5
    }
118
119
    void Ed25519Authenticator::Serialize(Serialization &serializer) const
120
11
    {
121
11
        serializer.Serialize(m_publicKey);
122
11
        m_signature.Serialize(serializer);
123
11
    }
124
125
    std::shared_ptr<ISerializable> Ed25519Authenticator::Deserialize(Deserialization &deserializer)
126
5
    {
127
5
        auto key = std::dynamic_pointer_cast<PublicKey>(PublicKey::Deserialize(deserializer));
128
5
        auto signature = std::dynamic_pointer_cast<Signature>(Signature::Deserialize(deserializer));
129
5
        return std::make_shared<Ed25519Authenticator>(*key, *signature);
130
5
    }
131
132
    bool Ed25519Authenticator::Equals(const Ed25519Authenticator &other) const
133
5
    {
134
5
        return m_publicKey.Equals(other.m_publicKey) && m_signature.Equals(other.m_signature);
135
5
    }
136
137
    int Ed25519Authenticator::GetHashCode() const
138
0
    {
139
0
        return 0;
140
        //    return m_publicKey.GetHashCode() + m_signature.GetHashCode();
141
0
    }
142
143
    std::string Ed25519Authenticator::ToString() const
144
0
    {
145
0
        return "PublicKey: " + m_publicKey.ToString() + ", Signature: " + m_signature.ToString();
146
0
    }
147
148
    MultiAgentAuthenticator::MultiAgentAuthenticator(Authenticator sender, const std::vector<std::tuple<std::shared_ptr<AccountAddress>, std::shared_ptr<Authenticator>>> &secondarySigners)
149
3
        : sender(sender), secondarySigners(secondarySigners) {}
150
151
    Sequence MultiAgentAuthenticator::SecondaryAddresses() const
152
2
    {
153
2
        std::vector<std::shared_ptr<ISerializable>> secondaryAddresses;
154
2
        for (const auto &signer : secondarySigners)
155
2
        {
156
2
            secondaryAddresses.push_back(std::get<0>(signer));
157
2
        }
158
2
        return Sequence(secondaryAddresses);
159
2
    }
160
161
    bool MultiAgentAuthenticator::Verify(const CryptoPP::SecByteBlock &data)
162
2
    {
163
2
        if (!sender.Verify(data))
164
0
        {
165
0
            return false;
166
0
        }
167
2
        for (const auto &signer : secondarySigners)
168
2
        {
169
2
            if (!std::get<1>(signer)->Verify(data))
170
0
            {
171
0
                return false;
172
0
            }
173
2
        }
174
175
2
        return true;
176
2
    }
177
178
    void MultiAgentAuthenticator::Serialize(Serialization &serializer) const
179
4
    {
180
4
        std::vector<std::shared_ptr<ISerializable>> secondaryAddresses;
181
4
        std::vector<std::shared_ptr<ISerializable>> authenticators;
182
4
        for (const auto &signer : secondarySigners)
183
4
        {
184
4
            secondaryAddresses.push_back(std::get<0>(signer));
185
4
            authenticators.push_back(std::get<1>(signer));
186
4
        }
187
188
4
        serializer.Serialize(sender);
189
4
        serializer.Serialize(Sequence(secondaryAddresses));
190
4
        serializer.Serialize(Sequence(authenticators));
191
4
    }
192
193
    std::shared_ptr<ISerializable> MultiAgentAuthenticator::Deserialize(Deserialization &deserializer)
194
2
    {
195
2
        std::shared_ptr<Authenticator> sender = std::dynamic_pointer_cast<Authenticator>(Authenticator::Deserialize(deserializer));
196
2
        std::vector<std::shared_ptr<ISerializable>> secondaryAddressesSeq = deserializer.DeserializeSequence(
197
2
            [](Deserialization &d) -> std::shared_ptr<ISerializable>
198
2
            { return AccountAddress::Deserialize(d); });
199
2
        std::vector<std::shared_ptr<ISerializable>> authenticatorsSeq = deserializer.DeserializeSequence(
200
2
            [](Deserialization &d) -> std::shared_ptr<ISerializable>
201
2
            { return Authenticator::Deserialize(d); });
202
203
2
        std::vector<std::tuple<std::shared_ptr<AccountAddress>, std::shared_ptr<Authenticator>>> secondarySigners;
204
4
        for (size_t i = 0; i < secondaryAddressesSeq.size(); i++)
205
2
        {
206
2
            secondarySigners.push_back(std::make_tuple(std::dynamic_pointer_cast<AccountAddress>(secondaryAddressesSeq[i]),
207
2
                                                       std::dynamic_pointer_cast<Authenticator>(authenticatorsSeq[i])));
208
2
        }
209
210
2
        return std::make_shared<MultiAgentAuthenticator>(*sender, secondarySigners);
211
2
    }
212
213
    bool MultiAgentAuthenticator::Equals(const MultiAgentAuthenticator &other) const
214
2
    {
215
216
2
        bool areEqual = secondarySigners.size() == other.secondarySigners.size();
217
218
2
        if (areEqual)
219
2
        {
220
4
            for (size_t i = 0; i < secondarySigners.size(); ++i)
221
2
            {
222
2
                std::shared_ptr<AccountAddress> addr1 = std::get<0>(secondarySigners[i]);
223
2
                std::shared_ptr<Authenticator> auth1 = std::get<1>(secondarySigners[i]);
224
225
2
                std::shared_ptr<AccountAddress> addr2 = std::get<0>(other.secondarySigners[i]);
226
2
                std::shared_ptr<Authenticator> auth2 = std::get<1>(other.secondarySigners[i]);
227
228
2
                if (!(*addr1 == *addr2) || !(*auth1 == *auth2))
229
0
                {
230
0
                    areEqual = false;
231
0
                    break;
232
0
                }
233
2
            }
234
2
        }
235
236
2
        return (sender.Equals(other.sender) && areEqual);
237
2
    }
238
239
    int MultiAgentAuthenticator::GetHashCode() const
240
0
    {
241
0
        return 0; // You need to implement this
242
0
    }
243
244
    std::string MultiAgentAuthenticator::ToString() const
245
0
    {
246
0
        return "MultiAgentAuthenticator";
247
0
    }
248
249
    MultiEd25519Authenticator::MultiEd25519Authenticator(MultiPublicKey publicKey, MultiSignature signature)
250
0
        : m_publicKey(publicKey), m_signature(signature) {}
251
252
    bool MultiEd25519Authenticator::Verify(const CryptoPP::SecByteBlock &data)
253
0
    {
254
        // Implement this
255
0
        return false;
256
0
    }
257
258
    void MultiEd25519Authenticator::Serialize(Serialization &serializer) const
259
0
    {
260
0
        serializer.Serialize(m_publicKey);
261
0
        serializer.Serialize(m_signature);
262
0
    }
263
264
    bool MultiEd25519Authenticator::Equals(const MultiAgentAuthenticator &other) const
265
0
    {
266
0
        return false;
267
        //    return m_publicKey.Equals(other.m_publicKey) && m_signature.Equals(other.m_signature);
268
0
    }
269
270
    std::shared_ptr<ISerializable> MultiEd25519Authenticator::Deserialize(Deserialization &deserializer)
271
0
    {
272
        // Implement this
273
0
        return nullptr;
274
0
    }
275
276
    bool operator==(const Authenticator &lhs, const Authenticator &rhs)
277
4
    {
278
4
        return lhs.Equals(rhs);
279
4
    }
280
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/BCSMap.cpp
Line
Count
Source
1
//
2
// Created by Anh NPH on 22/09/2023.
3
//
4
5
#include "BCSMap.h"
6
#include "Serialization.h"
7
#include "Deserialization.h"
8
#include <sstream>
9
10
namespace Aptos::BCS
11
{
12
    std::map<BString, std::shared_ptr<ISerializable>> BCSMap::getValues() const
13
1
    {
14
1
        return values;
15
1
    }
16
17
    BCSMap::BCSMap(const std::map<BString, std::shared_ptr<ISerializable>> &values)
18
        : values(values)
19
9
    {
20
9
    }
21
22
    void BCSMap::Serialize(Serialization &serializer) const
23
7
    {
24
7
        Serialization mapSerializer;
25
7
        std::map<std::string, std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> byteMap;
26
27
7
        for (const auto &entry : this->values)
28
20
        {
29
20
            Serialization keySerializer;
30
20
            static_cast<BString>(entry.first).Serialize(keySerializer);
31
20
            std::vector<uint8_t> bKey = keySerializer.GetBytes();
32
33
20
            Serialization valSerializer;
34
20
            entry.second->Serialize(valSerializer);
35
20
            std::vector<uint8_t> bValue = valSerializer.GetBytes();
36
37
20
            byteMap.insert({entry.first.GetValue(), {bKey, bValue}});
38
20
        }
39
7
        mapSerializer.SerializeU32AsUleb128(byteMap.size());
40
41
7
        for (const auto &entry : byteMap)
42
20
        {
43
20
            mapSerializer.SerializeFixedBytes(entry.second.first);
44
20
            mapSerializer.SerializeFixedBytes(entry.second.second);
45
20
        }
46
47
7
        serializer.SerializeFixedBytes(mapSerializer.GetBytes());
48
7
    }
49
50
    std::string BCSMap::ToString() const
51
1
    {
52
1
        std::stringstream ss;
53
1
        for (const auto &entry : values)
54
2
            ss << "(" << entry.first.ToString() << ", " << entry.second->ToString() << ")";
55
1
        return ss.str();
56
1
    }
57
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/BCSTypes.cpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Created by Anh NPH on 21/09/2023.
3
//
4
5
#include "BCSTypes.h"
6
#include "Deserialization.h"
7
#include <algorithm>
8
#include "Bool.h"
9
#include "U8.h"
10
#include "U16.h"
11
#include "U32.h"
12
#include "U64.h"
13
#include "U128.h"
14
#include "U256.h"
15
#include "../Accounts/AccountAddress.h"
16
#include "StructTag.h"
17
18
namespace Aptos::BCS
19
{
20
    std::shared_ptr<ISerializableTag> ISerializableTag::DeserializeTag(Deserialization &deserializer)
21
10
    {
22
10
        TypeTag variant = static_cast<TypeTag>(deserializer.DeserializeUleb128());
23
24
10
        switch (variant)
25
10
        {
26
1
        case TypeTag::BOOL:
27
1
            return Bool::Deserialize(deserializer);
28
1
        case TypeTag::U8:
29
1
            return U8::Deserialize(deserializer);
30
1
        case TypeTag::U16:
31
1
            return U16::Deserialize(deserializer);
32
1
        case TypeTag::U32:
33
1
            return U32::Deserialize(deserializer);
34
1
        case TypeTag::U64:
35
1
            return U64::Deserialize(deserializer);
36
1
        case TypeTag::U128:
37
1
            return U128::Deserialize(deserializer);
38
1
        case TypeTag::U256:
39
1
            return U256::Deserialize(deserializer);
40
1
        case TypeTag::ACCOUNT_ADDRESS:
41
1
            return Accounts::AccountAddress::Deserialize(deserializer);
42
2
        case TypeTag::STRUCT:
43
2
            return StructTag::Deserialize(deserializer);
44
0
        default:
45
0
            throw std::logic_error("The method or operation is not implemented.");
46
10
        }
47
10
    }
48
49
    std::string ISerializableTag::ToString() const
50
0
    {
51
0
        std::string typeTagStr;
52
0
        switch (Variant())
53
0
        {
54
0
        case TypeTag::BOOL:
55
0
            typeTagStr = "BOOL";
56
0
            break;
57
0
        case TypeTag::U8:
58
0
            typeTagStr = "U8";
59
0
            break;
60
0
        case TypeTag::U64:
61
0
            typeTagStr = "U64";
62
0
            break;
63
0
        case TypeTag::U128:
64
0
            typeTagStr = "U128";
65
0
            break;
66
0
        case TypeTag::ACCOUNT_ADDRESS:
67
0
            typeTagStr = "ACCOUNT_ADDRESS";
68
0
            break;
69
0
        case TypeTag::SIGNER:
70
0
            typeTagStr = "SIGNER";
71
0
            break;
72
0
        case TypeTag::VECTOR:
73
0
            typeTagStr = "VECTOR";
74
0
            break;
75
0
        case TypeTag::STRUCT:
76
0
            typeTagStr = "STRUCT";
77
0
            break;
78
0
        case TypeTag::U16:
79
0
            typeTagStr = "U16";
80
0
            break;
81
0
        case TypeTag::U32:
82
0
            typeTagStr = "U32";
83
0
            break;
84
0
        case TypeTag::U256:
85
0
            typeTagStr = "U256";
86
0
            break;
87
0
        default:
88
0
            typeTagStr = "UNKNOWN";
89
0
        }
90
0
        return "ISerializableTag (" + typeTagStr + ")";
91
0
    }
92
93
    std::shared_ptr<ISerializable> ISerializable::Deserialize(Deserialization &deserializer)
94
0
    {
95
0
        throw std::logic_error("The method or operation is not implemented.");
96
0
        return nullptr;
97
0
    }
98
99
    std::size_t ISerializable::GetHashCode()
100
4
    {
101
        // Your hash logic here. This is just a simple example.
102
4
        std::size_t seed = 0;
103
        // boost::hash_combine(seed, int_member);
104
        // boost::hash_combine(seed, boost::hash_value(string_member));
105
4
        return seed;
106
4
    }
107
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/BCSTypes.h
Line
Count
Source (jump to first uncovered line)
1
//
2
// Created by Anh NPH on 21/09/2023.
3
//
4
5
#ifndef APTOS_BCSTYPES_H
6
#define APTOS_BCSTYPES_H
7
#include <stdexcept>
8
#include <vector>
9
#include <string>
10
#include <cstdint>
11
#include <memory>
12
13
namespace Aptos::BCS
14
{
15
    class Serialization;
16
    class Deserialization;
17
18
    // See type_tag.py
19
    enum class TypeTag
20
    {
21
        BOOL,            // int = 0
22
        U8,              // int = 1
23
        U64,             // int = 2
24
        U128,            // int = 3
25
        ACCOUNT_ADDRESS, // int = 4
26
        SIGNER,          // int = 5
27
        VECTOR,          // int = 6
28
        STRUCT,          // int = 7
29
        U16,
30
        U32,
31
        U256,
32
        SCRIPT,
33
        ENTRY_FUNCTION,
34
    };
35
36
    /// <summary>
37
    /// An interfaces that enforces types to implement a serialization method.
38
    /// </summary>
39
    class ISerializable
40
    {
41
    public:
42
        /// <summary>
43
        /// Serialize the object.
44
        /// </summary>
45
        /// <param name="serializer"></param>
46
        virtual void Serialize(Serialization &serializer) const = 0;
47
48
        /// <summary>
49
        /// Deserializes a byte array hosted inside the Deserializer.
50
        /// </summary>
51
        /// <param name="deserializer"></param>
52
        /// <returns></returns>
53
        static std::shared_ptr<ISerializable> Deserialize(Deserialization &deserializer);
54
        virtual std::size_t GetHashCode();
55
        ;
56
1.35k
        virtual ~ISerializable() {}
57
        virtual std::string ToString() const = 0;
58
    };
59
60
    class ISerializableTag : public ISerializable
61
    {
62
    public:
63
        /// <summary>
64
        /// Returns the type of type tag.
65
        /// </summary>
66
        /// <returns>A TypeTag enum.</returns>
67
        virtual TypeTag Variant() const = 0;
68
69
        /// <summary>
70
        /// Serializes the type tag using it's own serializaton method.
71
        /// </summary>
72
        /// <param name="serializer"></param>
73
        virtual void SerializeTag(Serialization &serializer)
74
0
        {
75
0
            this->Serialize(serializer);
76
0
        }
77
78
        /// <summary>
79
        /// Deserialize a tag based on it's type.
80
        /// </summary>
81
        /// <param name="deserializer"></param>
82
        /// <returns>An object.</returns>
83
        static std::shared_ptr<ISerializableTag> DeserializeTag(Deserialization &deserializer);
84
478
        virtual ~ISerializableTag() {}
85
86
        std::string ToString() const override;
87
    };
88
}
89
#endif // APTOS_BCSTYPES_H
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/BString.cpp
Line
Count
Source
1
//
2
// Created by Anh NPH on 22/09/2023.
3
//
4
5
#include "BString.h"
6
#include "Deserialization.h"
7
#include "Serialization.h"
8
#include <functional>
9
10
namespace Aptos::BCS
11
{
12
    BString::BString() : ISerializable()
13
1
    {
14
1
    }
15
16
    BString::BString(const std::string &value)
17
73
        : ISerializable(), value(value) {}
18
19
    void BString::Serialize(Serialization &serializer) const
20
51
    {
21
51
        serializer.Serialize(value);
22
51
    }
23
24
    std::shared_ptr<ISerializable> BString::Deserialize(Deserialization &deserializer)
25
4
    {
26
4
        std::string deserStr = deserializer.DeserializeString();
27
4
        return std::make_shared<BString>(deserStr);
28
4
    }
29
30
    bool BString::Equals(const BString &other) const
31
5
    {
32
5
        return this->value == other.value;
33
5
    }
34
35
    std::string BString::ToString() const
36
13
    {
37
13
        return value;
38
13
    }
39
40
    size_t BString::GetHashCode() const
41
2
    {
42
2
        return std::hash<std::string>{}(value);
43
2
    }
44
45
    std::string BString::GetValue() const
46
20
    {
47
20
        return value;
48
20
    }
49
50
    std::vector<uint8_t> BString::RemoveBOM(const std::vector<uint8_t> &data)
51
2
    {
52
2
        std::vector<uint8_t> bom = {0xEF, 0xBB, 0xBF}; // UTF-8 BOM
53
54
2
        if (data.size() > bom.size())
55
2
        {
56
2
            if (std::equal(bom.begin(), bom.end(), data.begin()))
57
1
            {
58
1
                return std::vector<uint8_t>(data.begin() + bom.size(), data.end());
59
1
            }
60
2
        }
61
62
1
        return data;
63
2
    }
64
65
    bool BString::operator<(const BString &other) const
66
56
    {
67
56
        return this->value < other.value;
68
56
    }
69
70
    std::string BString::Deserialize(const std::vector<uint8_t> &data)
71
19
    {
72
19
        return std::string(data.begin(), data.end());
73
19
    }
74
75
    bool BString::operator==(const BString &other) const
76
2
    {
77
2
        return this->value == other.value;
78
2
    }
79
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/Bool.cpp
Line
Count
Source
1
//
2
// Created by Anh NPH on 21/09/2023.
3
//
4
5
#include "Bool.h"
6
#include "Serialization.h"
7
#include "Deserialization.h"
8
9
namespace Aptos::BCS
10
{
11
    Bool::Bool(bool value)
12
34
    {
13
34
        this->value = value;
14
34
    }
15
16
    void Bool::Serialize(Serialization &serializer) const
17
20
    {
18
20
        serializer.SerializeBool(this->value);
19
20
    }
20
21
    std::shared_ptr<ISerializableTag> Bool::Deserialize(Deserialization &deserializer)
22
4
    {
23
4
        bool value = deserializer.DeserializeBool();
24
4
        return std::make_shared<Bool>(value);
25
4
    }
26
27
    TypeTag Bool::Variant() const
28
2
    {
29
2
        return TypeTag::BOOL;
30
2
    }
31
32
    bool Bool::GetValue() const
33
3
    {
34
3
        return value;
35
3
    }
36
37
    bool Bool::Equals(const Bool &other) const
38
3
    {
39
3
        return this->value == other.value;
40
3
    }
41
42
    std::string Bool::ToString() const
43
4
    {
44
4
        return this->value ? "true" : "false";
45
4
    }
46
47
    size_t Bool::GetHashCode() const
48
4
    {
49
        // Simple hash code calculation, more sophisticated method might be needed
50
4
        return std::hash<bool>{}(this->value);
51
4
    }
52
53
    bool operator==(const Bool &lhs, const Bool &rhs)
54
3
    {
55
3
        return lhs.Equals(rhs);
56
3
    }
57
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/Bytes.cpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Created by Anh NPH on 21/09/2023.
3
//
4
5
#include "Bytes.h"
6
7
#include "Bytes.h"
8
#include <algorithm>
9
#include <sstream>
10
#include <functional>
11
#include "Serialization.h"
12
#include "Deserialization.h"
13
14
namespace Aptos::BCS
15
{
16
    Bytes::Bytes(const std::vector<uint8_t> &values)
17
72
    {
18
72
        this->values = values;
19
72
    }
20
21
    void Bytes::Serialize(Serialization &serializer) const
22
115
    {
23
115
        serializer.SerializeBytes(this->values);
24
115
    }
25
26
    Bytes *Bytes::Deserialize(Deserialization &deserializer)
27
0
    {
28
0
        std::vector<uint8_t> values = deserializer.ToBytes();
29
0
        return new Bytes(values);
30
0
    }
31
32
    std::vector<uint8_t> Bytes::getValue() const
33
1
    {
34
1
        return this->values;
35
1
    }
36
37
    bool Bytes::Equals(const Bytes &other) const
38
2
    {
39
2
        return std::equal(this->values.begin(), this->values.end(), other.values.begin());
40
2
    }
41
42
    std::string Bytes::ToString() const
43
4
    {
44
4
        std::ostringstream oss;
45
4
        for (const auto &value : values)
46
50
            oss << static_cast<int>(value);
47
4
        return oss.str();
48
4
    }
49
50
    size_t Bytes::GetHashCode() const
51
1
    {
52
        // Simple hash code calculation, more sophisticated method might be needed
53
1
        return std::hash<std::string>{}(this->ToString());
54
1
    }
55
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/Deserialization.cpp
Line
Count
Source (jump to first uncovered line)
1
// Deserialization.cpp
2
#include "Deserialization.h"
3
#include "Sequence.h"
4
#include "Serialization.h"
5
// #include "BCS.h"
6
#include <algorithm>
7
#include "U16.h"
8
#include "U32.h"
9
#include "U64.h"
10
#include "U128.h"
11
#include "U256.h"
12
#include "BString.h"
13
#include "TagSequence.h"
14
#include "ScriptArgument.h"
15
16
namespace Aptos::BCS
17
{
18
    Deserialization::Deserialization(const std::vector<uint8_t> &data) : buffer(data), position(0)
19
39
    {
20
39
    }
21
22
    std::size_t Deserialization::Remaining() const
23
2
    {
24
2
        return buffer.size() - position;
25
2
    }
26
27
    bool Deserialization::DeserializeBool()
28
6
    {
29
6
        auto bytes = Read(1);
30
6
        return bytes[0] != 0;
31
6
    }
32
33
    std::vector<uint8_t> Deserialization::ToBytes()
34
25
    {
35
25
        auto len = DeserializeUleb128();
36
25
        return Read(len);
37
25
    }
38
39
    std::vector<uint8_t> Deserialization::FixedBytes(std::size_t length)
40
14
    {
41
14
        return Read(length);
42
14
    }
43
44
    std::vector<uint8_t> Deserialization::Read(std::size_t length)
45
192
    {
46
192
        if (position + length > buffer.size())
47
1
        {
48
1
            throw std::runtime_error("Unexpected end of input.");
49
1
        }
50
51
191
        std::vector<uint8_t> result(buffer.begin() + position, buffer.begin() + position + length);
52
191
        position += length;
53
191
        return result;
54
192
    }
55
56
    uint8_t Deserialization::ReadInt(std::size_t length)
57
98
    {
58
98
        auto bytes = Read(length);
59
98
        return bytes[0];
60
98
    }
61
62
    uint8_t Deserialization::DeserializeU8()
63
11
    {
64
11
        return ReadInt(1);
65
11
    }
66
67
    uint16_t Deserialization::DeserializeU16()
68
2
    {
69
2
        return U16::Deserialize(this->Read(2));
70
2
    }
71
    uint32_t Deserialization::DeserializeU32()
72
5
    {
73
5
        return U32::Deserialize(this->Read(4));
74
5
    }
75
    uint64_t Deserialization::DeserializeU64()
76
17
    {
77
17
        return U64::Deserialize(this->Read(8));
78
17
    }
79
80
    std::size_t Deserialization::DeserializeUleb128()
81
84
    {
82
84
        std::size_t value = 0;
83
84
        int shift = 0;
84
85
87
        while (true)
86
87
        {
87
87
            uint8_t byteRead = ReadInt(1);
88
87
            value |= (byteRead & 0x7F) << shift;
89
90
87
            if ((byteRead & 0x80) == 0)
91
84
                break;
92
3
            shift += 7;
93
3
        }
94
95
84
        if (value > std::pow(2, 128) - 1)
96
0
        {
97
0
            throw std::runtime_error("Unexpectedly large uleb128 value");
98
0
        }
99
100
84
        return value;
101
84
    }
102
103
    CryptoPP::Integer Deserialization::DeserializeU128()
104
4
    {
105
4
        return U128::Deserialize(this->Read(16));
106
4
    }
107
108
    CryptoPP::Integer Deserialization::DeserializeU256()
109
2
    {
110
2
        return U256::Deserialize(this->Read(32));
111
2
    }
112
113
    std::string Deserialization::DeserializeString()
114
19
    {
115
19
        return BString::Deserialize(this->Read(this->DeserializeUleb128()));
116
19
    }
117
118
    BCSMap Deserialization::DeserializeMap(std::function<std::shared_ptr<ISerializable>(Deserialization &)> deserializeFunc)
119
1
    {
120
        // Read the number of key-value pairs
121
1
        uint32_t numPairs = this->DeserializeUleb128();
122
123
1
        std::map<std::string, std::shared_ptr<ISerializable>> sortedMap;
124
125
        // Deserialize each key-value pair
126
4
        for (uint32_t i = 0; i < numPairs; i++)
127
3
        {
128
            // Deserialize the key
129
3
            std::string key = this->DeserializeString();
130
131
            // Add the key-value pair to the map
132
3
            sortedMap[key] = deserializeFunc(*this);
133
3
        }
134
135
1
        std::map<BString, std::shared_ptr<ISerializable>> values;
136
1
        for (const auto &entry : sortedMap)
137
3
        {
138
3
            values[BString(entry.first)] = entry.second;
139
3
        }
140
141
        // Construct a new BCSMap object and return it
142
1
        return BCSMap(values);
143
1
    }
144
145
    std::vector<std::shared_ptr<ISerializable>> Deserialization::DeserializeSequence(std::function<std::shared_ptr<ISerializable>(Deserialization &)> deserializeFunc)
146
6
    {
147
        // Read the number of values
148
6
        uint32_t numPairs = this->DeserializeUleb128();
149
150
6
        std::vector<std::shared_ptr<ISerializable>> values;
151
152
        // Deserialize each value
153
17
        for (uint32_t i = 0; i < numPairs; i++)
154
11
        {
155
            // Deserialize the value
156
11
            values.push_back(deserializeFunc(*this));
157
11
        }
158
159
6
        return values;
160
6
    }
161
162
    std::shared_ptr<TagSequence> Deserialization::DeserializeTagSequence()
163
4
    {
164
4
        int length = DeserializeUleb128();
165
4
        std::vector<std::shared_ptr<ISerializableTag>> values;
166
167
5
        while (values.size() < length)
168
1
        {
169
1
            std::shared_ptr<ISerializableTag> val = ISerializableTag::DeserializeTag(*this);
170
1
            values.push_back(val);
171
1
        }
172
173
4
        return std::make_shared<TagSequence>(values);
174
4
    }
175
176
    std::shared_ptr<Sequence> Deserialization::DeserializeScriptArgSequence()
177
1
    {
178
1
        int length = DeserializeUleb128();
179
1
        std::vector<std::shared_ptr<ISerializable>> values;
180
181
6
        while (values.size() < length)
182
5
        {
183
5
            std::shared_ptr<ISerializable> val = ScriptArgument::Deserialize(*this);
184
5
            values.push_back(val);
185
5
        }
186
1
        return std::make_shared<Sequence>(values);
187
1
    }
188
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/EntryFunction.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "EntryFunction.h"
2
#include <stdexcept>
3
#include "Bytes.h"
4
5
namespace Aptos::BCS
6
{
7
    EntryFunction::EntryFunction(const ModuleId &module, const std::string &function, const TagSequence &typeArgs, const Sequence &args)
8
30
        : module(module), function(function), typeArgs(typeArgs), args(args) {}
9
10
    EntryFunction EntryFunction::Natural(const ModuleId &module, const std::string &function, const TagSequence &typeArgs, const Sequence &args)
11
27
    {
12
27
        auto value = args.GetValue();
13
14
27
        std::vector<std::shared_ptr<ISerializable>> valuesAsBytes;
15
16
27
        for (const auto &element : value)
17
50
        {
18
50
            if (std::dynamic_pointer_cast<Sequence>(element))
19
13
            {
20
13
                Serialization seqSerializer;
21
13
                auto seq = std::dynamic_pointer_cast<Sequence>(element);
22
13
                seqSerializer.Serialize(*seq);
23
24
13
                auto bytes = seqSerializer.GetBytes();
25
13
                valuesAsBytes.push_back(std::make_shared<Bytes>(bytes));
26
13
            }
27
37
            else
28
37
            {
29
37
                Serialization s;
30
37
                element->Serialize(s);
31
37
                auto bytes = s.GetBytes();
32
37
                valuesAsBytes.push_back(std::make_shared<Bytes>(bytes));
33
37
            }
34
50
        }
35
36
27
        Sequence seqBytes(valuesAsBytes);
37
27
        return EntryFunction(module, function, typeArgs, seqBytes);
38
27
    }
39
40
    void EntryFunction::Serialize(Serialization &serializer) const
41
32
    {
42
32
        serializer.Serialize(module);
43
32
        serializer.SerializeString(function);
44
32
        serializer.Serialize(typeArgs);
45
32
        serializer.Serialize(args);
46
32
    }
47
48
    std::shared_ptr<ISerializable> EntryFunction::Deserialize(Deserialization &deserializer)
49
3
    {
50
3
        auto module = std::dynamic_pointer_cast<ModuleId>(ModuleId::Deserialize(deserializer));
51
3
        std::string function = deserializer.DeserializeString();
52
3
        auto typeArgs = std::dynamic_pointer_cast<TagSequence>(deserializer.DeserializeTagSequence());
53
3
        auto args = std::dynamic_pointer_cast<Sequence>(Sequence::Deserialize(deserializer));
54
3
        return std::make_shared<EntryFunction>(*module, function, *typeArgs, *args);
55
3
    }
56
57
    bool EntryFunction::Equals(const EntryFunction &other) const
58
6
    {
59
6
        bool moduleComparison = module.Equals(other.module);
60
6
        bool entryFuncComparison = function == other.function;
61
6
        bool typeArgsComparison = typeArgs.Equals(other.typeArgs);
62
6
        bool argsComparison = args.Equals(other.args);
63
6
        return moduleComparison && entryFuncComparison && typeArgsComparison && argsComparison;
64
6
    }
65
66
    std::string EntryFunction::ToString() const
67
1
    {
68
1
        return module.ToString() + "::" + function + "<" + typeArgs.ToString() + ">(" + args.ToString() + ")";
69
1
    }
70
71
    size_t EntryFunction::GetHashCode() const
72
0
    {
73
0
        size_t hash = 17;
74
0
        hash = hash * 23 + module.GetHashCode();
75
0
        hash = hash * 23 + std::hash<std::string>{}(function);
76
0
        hash = hash * 23 + typeArgs.GetHashCode();
77
0
        hash = hash * 23 + args.GetHashCode();
78
0
        return hash;
79
0
    }
80
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/ModuleId.cpp
Line
Count
Source
1
#include "ModuleId.h"
2
3
namespace Aptos::BCS
4
{
5
    ModuleId::ModuleId(const AccountAddress &address, const std::string &name)
6
43
        : address(address), name(name) {}
7
8
    void ModuleId::Serialize(Serialization &serializer) const
9
33
    {
10
33
        address.Serialize(serializer);
11
33
        serializer.SerializeString(name);
12
33
    }
13
14
    std::shared_ptr<ISerializable> ModuleId::Deserialize(Deserialization &deserializer)
15
3
    {
16
3
        auto addr = std::dynamic_pointer_cast<AccountAddress>(AccountAddress::Deserialize(deserializer));
17
3
        std::string name = deserializer.DeserializeString();
18
3
        return std::make_shared<ModuleId>(*addr, name);
19
3
    }
20
21
    bool ModuleId::Equals(const ModuleId &other) const
22
12
    {
23
12
        return address == other.address && name == other.name;
24
12
    }
25
26
    std::string ModuleId::ToString() const
27
3
    {
28
3
        return address.ToString() + "::" + name;
29
3
    }
30
31
    ModuleId ModuleId::FromStr(const std::string &moduleId)
32
6
    {
33
6
        if (moduleId.empty())
34
1
        {
35
1
            throw std::invalid_argument("ModuleId string is empty.");
36
1
        }
37
38
5
        size_t pos = moduleId.find("::");
39
5
        if (pos == std::string::npos || pos == 0 || pos == moduleId.size() - 2)
40
3
        {
41
3
            throw std::invalid_argument("Invalid ModuleId format.");
42
3
        }
43
44
2
        std::string addressStr = moduleId.substr(0, pos);
45
2
        AccountAddress accountAddress = AccountAddress::FromHex(addressStr);
46
2
        std::string name = moduleId.substr(pos + 2);
47
48
2
        return ModuleId(accountAddress, name);
49
5
    }
50
51
    size_t ModuleId::GetHashCode() const
52
1
    {
53
1
        return 0;
54
        //    size_t hash = 17;
55
        //    hash = hash * 23 + address.GetHashCode();
56
        //    hash = hash * 23 + std::hash<std::string>{}(name);
57
        //    return hash;
58
1
    }
59
60
    bool operator==(const ModuleId &lhs, const ModuleId &rhs)
61
3
    {
62
3
        return lhs.Equals(rhs);
63
3
    }
64
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/MultiAgentRawTransaction.cpp
Line
Count
Source
1
#include "MultiAgentRawTransaction.h"
2
#include <stdexcept>
3
#include "../HDWallet/Utils/Utils.h"
4
#include <cryptopp/sha3.h>
5
6
namespace Aptos::BCS
7
{
8
    MultiAgentRawTransaction::MultiAgentRawTransaction(const RawTransaction &rawTransaction, const Sequence &secondarySigners)
9
        : rawTransaction(rawTransaction), secondarySigners(secondarySigners)
10
3
    {
11
3
    }
12
13
    RawTransaction MultiAgentRawTransaction::Inner()
14
3
    {
15
3
        return this->rawTransaction;
16
3
    }
17
18
    std::vector<uint8_t> MultiAgentRawTransaction::Prehash()
19
7
    {
20
7
        CryptoPP::SHA3_256 sha3;
21
7
        std::string input = "APTOS::RawTransactionWithData";
22
7
        auto inputS = Utils::StringToSecByteBlock(input.data());
23
7
        sha3.Update(inputS, inputS.size());
24
7
        CryptoPP::SecByteBlock result(Utils::Ed25519PublicKeySizeInBytes); // 256 bits = 32 bytes
25
7
        sha3.Final(result);
26
27
7
        return Utils::SecBlockToByteVector(result);
28
7
    }
29
30
    std::vector<uint8_t> MultiAgentRawTransaction::Keyed()
31
7
    {
32
7
        Serialization ser;
33
7
        ser.SerializeU8(0);
34
7
        ser.Serialize(this->rawTransaction);
35
7
        ser.Serialize(this->secondarySigners);
36
7
        std::vector<uint8_t> prehash = this->Prehash();
37
7
        std::vector<uint8_t> outputBytes = ser.GetBytes();
38
7
        std::vector<uint8_t> res(prehash.size() + outputBytes.size());
39
40
7
        std::copy(prehash.begin(), prehash.end(), res.begin());
41
7
        std::copy(outputBytes.begin(), outputBytes.end(), res.begin() + prehash.size());
42
43
7
        return res;
44
7
    }
45
46
    Signature MultiAgentRawTransaction::Sign(PrivateKey key)
47
2
    {
48
2
        return key.Sign(Utils::ByteVectorToSecBlock(this->Keyed()));
49
2
    }
50
51
    bool MultiAgentRawTransaction::Verify(const PublicKey &key, const Signature &signature)
52
2
    {
53
2
        return key.Verify(Utils::ByteVectorToSecBlock(this->Keyed()), signature);
54
2
    }
55
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/Script.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "Script.h"
2
#include <stdexcept>
3
#include "Serialization.h"
4
#include "Deserialization.h"
5
#include <sstream>
6
7
namespace Aptos::BCS
8
{
9
    Script::Script(const std::vector<uint8_t> &code, const TagSequence &typeArgs, const Sequence &scriptArgs)
10
        : code(code), typeArgs(typeArgs), scriptArgs(scriptArgs)
11
7
    {
12
7
    }
13
14
    void Script::Serialize(Serialization &serializer) const
15
1
    {
16
1
        serializer.SerializeBytes(this->code);
17
1
        serializer.Serialize(this->typeArgs);
18
1
        serializer.Serialize(this->scriptArgs);
19
1
    }
20
21
    std::shared_ptr<ISerializable> Script::Deserialize(Deserialization &deserializer)
22
1
    {
23
1
        std::vector<uint8_t> code = deserializer.ToBytes();
24
1
        auto typeArgs = deserializer.DeserializeTagSequence();
25
1
        auto scriptArgs = deserializer.DeserializeScriptArgSequence();
26
1
        return std::make_shared<Script>(code, *typeArgs, *scriptArgs);
27
1
    }
28
29
    bool Script::Equals(const Script &other) const
30
3
    {
31
3
        bool codeComparison = this->code == other.code;
32
3
        bool typeArgsComparison = this->typeArgs.Equals(other.typeArgs);
33
3
        bool scriptArgsComparison = this->scriptArgs.Equals(other.scriptArgs);
34
3
        return codeComparison && typeArgsComparison && scriptArgsComparison;
35
3
    }
36
37
    std::string Script::ToString()
38
1
    {
39
1
        return "<" + this->typeArgs.ToString() + ">(" + this->scriptArgs.ToString() + ")";
40
1
    }
41
42
    size_t Script::GetHashCode()
43
1
    {
44
1
        size_t hash = 17;
45
1
        for (uint8_t byte : this->code)
46
5
        {
47
5
            hash = hash * 23 + static_cast<size_t>(byte);
48
5
        }
49
1
        hash = hash * 23 + this->typeArgs.GetHashCode();
50
1
        hash = hash * 23 + this->scriptArgs.GetHashCode();
51
1
        return hash;
52
1
    }
53
54
    std::string Script::ToString() const
55
0
    {
56
0
        std::stringstream ss;
57
0
        ss << "<" << this->typeArgs.ToString() << ">(" << this->scriptArgs.ToString() << ")";
58
0
        return ss.str();
59
0
    }
60
61
    bool operator==(const Script &lhs, const Script &rhs)
62
1
    {
63
1
        return lhs.Equals(rhs);
64
1
    }
65
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/ScriptArgument.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "ScriptArgument.h"
2
#include <stdexcept>
3
#include "Bool.h"
4
#include "Serialization.h"
5
#include "../Accounts/AccountAddress.h"
6
#include "U128.h"
7
#include "U16.h"
8
#include "U256.h"
9
#include "U32.h"
10
#include "U64.h"
11
#include "U8.h"
12
13
using namespace Aptos::Accounts;
14
namespace Aptos::BCS
15
{
16
    ScriptArgument::ScriptArgument(ScriptArgumentTypeTag variant, std::shared_ptr<ISerializableTag> value)
17
10
    {
18
10
        if (variant < ScriptArgumentTypeTag::U8 || variant > ScriptArgumentTypeTag::BOOL)
19
0
        {
20
0
            throw std::invalid_argument("Invalid variant");
21
0
        }
22
23
10
        this->variant = variant;
24
10
        this->value = value;
25
10
    }
26
27
    void ScriptArgument::Serialize(Serialization &serializer) const
28
15
    {
29
15
        serializer.SerializeU8(static_cast<uint8_t>(this->variant));
30
15
        if (this->variant == ScriptArgumentTypeTag::U8)
31
0
        {
32
0
            serializer.SerializeU8(std::dynamic_pointer_cast<U8>(this->value)->GetValue());
33
0
        }
34
15
        else if (this->variant == ScriptArgumentTypeTag::U16)
35
0
        {
36
0
            serializer.SerializeU16(std::dynamic_pointer_cast<U16>(this->value)->GetValue());
37
0
        }
38
15
        else if (this->variant == ScriptArgumentTypeTag::U32)
39
0
        {
40
0
            serializer.SerializeU32(std::dynamic_pointer_cast<U32>(this->value)->GetValue());
41
0
        }
42
15
        else if (this->variant == ScriptArgumentTypeTag::U64)
43
9
        {
44
9
            serializer.SerializeU64(std::dynamic_pointer_cast<U64>(this->value)->GetValue());
45
9
        }
46
6
        else if (this->variant == ScriptArgumentTypeTag::U128)
47
0
        {
48
0
            serializer.SerializeU128(std::dynamic_pointer_cast<U128>(this->value)->GetValue());
49
0
        }
50
6
        else if (this->variant == ScriptArgumentTypeTag::U256)
51
0
        {
52
0
            serializer.SerializeU256(std::dynamic_pointer_cast<U256>(this->value)->GetValue());
53
0
        }
54
6
        else if (this->variant == ScriptArgumentTypeTag::ACCOUNT_ADDRESS)
55
6
        {
56
6
            serializer.Serialize(*std::dynamic_pointer_cast<AccountAddress>(this->value));
57
6
        }
58
0
        else if (this->variant == ScriptArgumentTypeTag::BOOL)
59
0
        {
60
0
            serializer.SerializeBool(std::dynamic_pointer_cast<Bool>(this->value)->GetValue());
61
0
        }
62
0
        else
63
0
        {
64
0
            throw std::invalid_argument("Invalid ScriptArgument variant " + std::to_string(static_cast<uint8_t>(this->variant)));
65
0
        }
66
15
    }
67
68
    std::shared_ptr<ISerializable> ScriptArgument::Deserialize(Deserialization &deserializer)
69
5
    {
70
5
        ScriptArgumentTypeTag variant = static_cast<ScriptArgumentTypeTag>(deserializer.DeserializeU8());
71
5
        std::shared_ptr<ISerializableTag> value;
72
73
5
        if (variant == ScriptArgumentTypeTag::U8)
74
0
        {
75
0
            value = std::make_shared<U8>(deserializer.DeserializeU8());
76
0
        }
77
5
        else if (variant == ScriptArgumentTypeTag::U16)
78
0
        {
79
0
            value = std::make_shared<U16>(deserializer.DeserializeU16());
80
0
        }
81
5
        else if (variant == ScriptArgumentTypeTag::U32)
82
0
        {
83
0
            value = std::make_shared<U32>(deserializer.DeserializeU32());
84
0
        }
85
5
        else if (variant == ScriptArgumentTypeTag::U64)
86
3
        {
87
3
            value = std::make_shared<U64>(deserializer.DeserializeU64());
88
3
        }
89
2
        else if (variant == ScriptArgumentTypeTag::U128)
90
0
        {
91
0
            value = std::make_shared<U128>(deserializer.DeserializeU128());
92
0
        }
93
2
        else if (variant == ScriptArgumentTypeTag::U256)
94
0
        {
95
0
            value = std::make_shared<U256>(deserializer.DeserializeU256());
96
0
        }
97
2
        else if (variant == ScriptArgumentTypeTag::ACCOUNT_ADDRESS)
98
2
        {
99
2
            value = AccountAddress::Deserialize(deserializer);
100
2
        }
101
0
        else if (variant == ScriptArgumentTypeTag::BOOL)
102
0
        {
103
0
            value = std::make_shared<Bool>(deserializer.DeserializeBool());
104
0
        }
105
0
        else
106
0
        {
107
0
            throw std::invalid_argument("Invalid variant");
108
0
        }
109
110
5
        return std::make_shared<ScriptArgument>(variant, value);
111
5
    }
112
113
    bool ScriptArgument::Equals(const ScriptArgument &other)
114
0
    {
115
0
        if (variant == other.variant)
116
0
        {
117
0
            if (variant == ScriptArgumentTypeTag::U8)
118
0
            {
119
0
                return std::dynamic_pointer_cast<U8>(value)->Equals(*std::dynamic_pointer_cast<U8>(other.value));
120
0
            }
121
0
            else if (this->variant == ScriptArgumentTypeTag::U16)
122
0
            {
123
0
                return std::dynamic_pointer_cast<U16>(value)->Equals(*std::dynamic_pointer_cast<U16>(other.value));
124
0
            }
125
0
            else if (this->variant == ScriptArgumentTypeTag::U32)
126
0
            {
127
0
                return std::dynamic_pointer_cast<U32>(value)->Equals(*std::dynamic_pointer_cast<U32>(other.value));
128
0
            }
129
0
            else if (this->variant == ScriptArgumentTypeTag::U64)
130
0
            {
131
0
                return std::dynamic_pointer_cast<U64>(value)->Equals(*std::dynamic_pointer_cast<U64>(other.value));
132
0
            }
133
0
            else if (this->variant == ScriptArgumentTypeTag::U128)
134
0
            {
135
0
                return std::dynamic_pointer_cast<U128>(value)->Equals(*std::dynamic_pointer_cast<U128>(other.value));
136
0
            }
137
0
            else if (this->variant == ScriptArgumentTypeTag::U256)
138
0
            {
139
0
                return std::dynamic_pointer_cast<U256>(value)->Equals(*std::dynamic_pointer_cast<U256>(other.value));
140
0
            }
141
0
            else if (this->variant == ScriptArgumentTypeTag::ACCOUNT_ADDRESS)
142
0
            {
143
0
                return *std::dynamic_pointer_cast<AccountAddress>(value) == (*std::dynamic_pointer_cast<AccountAddress>(other.value));
144
0
            }
145
0
            else if (this->variant == ScriptArgumentTypeTag::BOOL)
146
0
            {
147
0
                return std::dynamic_pointer_cast<Bool>(value)->Equals(*std::dynamic_pointer_cast<Bool>(other.value));
148
0
            }
149
0
            else
150
0
            {
151
0
                return false;
152
0
            }
153
0
        }
154
0
        return false;
155
0
    }
156
157
    std::string ScriptArgument::ToString() const
158
0
    {
159
0
        return "[" + std::to_string(static_cast<uint8_t>(this->variant)) + "] " + this->value->ToString();
160
0
    }
161
162
    size_t ScriptArgument::GetHashCode()
163
0
    {
164
0
        size_t hash = 17;
165
0
        hash = hash * 23 + static_cast<size_t>(this->variant);
166
0
        hash = hash * 23 + this->value->GetHashCode();
167
0
        return hash;
168
0
    }
169
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/Sequence.cpp
Line
Count
Source
1
//
2
// Created by Anh NPH on 21/09/2023.
3
//
4
5
#include "Sequence.h"
6
#include <sstream>
7
#include <functional>
8
#include "Bytes.h"
9
#include "Serialization.h"
10
#include "Deserialization.h"
11
12
namespace Aptos::BCS
13
{
14
    Sequence::Sequence(const std::vector<std::shared_ptr<ISerializable>> &values)
15
98
    {
16
98
        this->values = values;
17
98
    }
18
19
    int Sequence::Length() const
20
2
    {
21
2
        return this->values.size();
22
2
    }
23
24
    std::vector<std::shared_ptr<ISerializable>> Sequence::GetValue() const
25
28
    {
26
28
        return values;
27
28
    }
28
29
    void Sequence::Serialize(Serialization &serializer) const
30
23
    {
31
23
        serializer.SerializeU32AsUleb128(this->values.size());
32
23
        for (const auto &element : this->values)
33
59
        {
34
59
            if (std::dynamic_pointer_cast<Sequence>(element))
35
1
            {
36
1
                Serialization seqSerializer;
37
1
                auto seq = std::dynamic_pointer_cast<Sequence>(element);
38
1
                seqSerializer.Serialize(*seq);
39
40
1
                std::vector<uint8_t> elementsBytes = seqSerializer.GetBytes();
41
1
                int sequenceLen = elementsBytes.size();
42
1
                serializer.SerializeU32AsUleb128(sequenceLen);
43
1
                serializer.SerializeFixedBytes(elementsBytes);
44
1
            }
45
58
            else
46
58
            {
47
58
                Serialization s;
48
58
                element->Serialize(s);
49
58
                std::vector<uint8_t> b = s.GetBytes();
50
58
                serializer.SerializeBytes(b);
51
58
            }
52
59
        }
53
23
    }
54
55
    std::shared_ptr<ISerializable> Sequence::Deserialize(Deserialization &deserializer)
56
4
    {
57
4
        int length = deserializer.DeserializeUleb128();
58
4
        std::vector<std::shared_ptr<ISerializable>> values;
59
60
15
        while (values.size() < length)
61
11
        {
62
11
            values.push_back(std::make_shared<Bytes>(deserializer.ToBytes()));
63
11
        }
64
65
4
        return std::make_shared<Sequence>(values);
66
4
    }
67
68
    bool Sequence::Equals(const Sequence &other) const
69
9
    {
70
9
        Serialization s1;
71
9
        this->Serialize(s1);
72
9
        Serialization s2;
73
9
        other.Serialize(s2);
74
9
        return s1.GetBytes() == s2.GetBytes();
75
9
    }
76
77
    std::string Sequence::ToString() const
78
3
    {
79
3
        std::ostringstream oss;
80
3
        for (const auto &value : this->values)
81
8
        {
82
8
            oss << value->ToString();
83
8
        }
84
3
        return oss.str();
85
3
    }
86
87
    size_t Sequence::GetHashCode() const
88
4
    {
89
4
        return 0;
90
4
    }
91
92
    const std::vector<std::shared_ptr<ISerializable>> &Sequence::getValues() const
93
62
    {
94
62
        return values;
95
62
    }
96
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/Serialization.cpp
Line
Count
Source
1
//
2
// Created by Anh NPH on 18/09/2023.
3
//
4
#include "Serialization.h"
5
#include <algorithm>
6
#include <filesystem>
7
8
namespace Aptos::BCS
9
{
10
    std::vector<uint8_t> Serialization::GetBytes()
11
432
    {
12
432
        return buffer;
13
432
    }
14
15
    Serialization &Serialization::Serialize(const std::string &value)
16
92
    {
17
92
        SerializeString(value);
18
92
        return *this;
19
92
    }
20
21
    Serialization &Serialization::Serialize(const std::vector<uint8_t> &value)
22
1
    {
23
1
        SerializeBytes(value);
24
1
        return *this;
25
1
    }
26
27
    Serialization &Serialization::Serialize(bool value)
28
1
    {
29
1
        SerializeBool(value);
30
1
        return *this;
31
1
    }
32
33
    Serialization &Serialization::Serialize(uint8_t num)
34
1
    {
35
1
        SerializeU8(num);
36
1
        return *this;
37
1
    }
38
39
    Serialization &Serialization::Serialize(uint16_t num)
40
1
    {
41
1
        SerializeU16(num);
42
1
        return *this;
43
1
    }
44
45
    Serialization &Serialization::Serialize(uint32_t num)
46
2
    {
47
2
        SerializeU32(num);
48
2
        return *this;
49
2
    }
50
51
    Serialization &Serialization::Serialize(uint64_t num)
52
1
    {
53
1
        SerializeU64(num);
54
1
        return *this;
55
1
    }
56
57
    Serialization &Serialization::Serialize(CryptoPP::Integer num)
58
1
    {
59
1
        SerializeU128(num);
60
1
        return *this;
61
1
    }
62
63
    Serialization &Serialization::Serialize(const ISerializable &value)
64
96
    {
65
96
        value.Serialize(*this);
66
96
        return *this;
67
96
    }
68
69
    Serialization &Serialization::SerializeString(const std::string &value)
70
161
    {
71
161
        std::vector<uint8_t> utf8_bytes(value.begin(), value.end());
72
161
        SerializeBytes(utf8_bytes);
73
161
        return *this;
74
161
    }
75
76
    Serialization &Serialization::SerializeBytes(const std::vector<uint8_t> &bytes)
77
370
    {
78
370
        SerializeU32AsUleb128(bytes.size());
79
370
        buffer.insert(buffer.end(), bytes.begin(), bytes.end());
80
370
        return *this;
81
370
    }
82
83
    Serialization &Serialization::SerializeFixedBytes(const std::vector<uint8_t> &bytes)
84
286
    {
85
286
        buffer.insert(buffer.end(), bytes.begin(), bytes.end());
86
286
        return *this;
87
286
    }
88
89
    Serialization &Serialization::SerializeU32AsUleb128(uint32_t value)
90
593
    {
91
599
        while (value >= 0x80)
92
6
        {
93
6
            uint8_t b = value & 0x7f;
94
6
            buffer.push_back(b | 0x80);
95
6
            value >>= 7;
96
6
        }
97
98
593
        buffer.push_back(value & 0x7f);
99
593
        return *this;
100
593
    }
101
102
    Serialization &Serialization::SerializeBool(bool value)
103
26
    {
104
26
        buffer.push_back(value ? 0x01 : 0x00);
105
26
        return *this;
106
26
    }
107
108
    Serialization &Serialization::SerializeU8(uint8_t num)
109
42
    {
110
42
        buffer.push_back(num);
111
42
        return *this;
112
42
    }
113
114
    Serialization &Serialization::SerializeU16(uint16_t num)
115
2
    {
116
2
        uint8_t lower = num & 0xFF;
117
2
        uint8_t upper = (num >> 8) & 0xFF;
118
2
        buffer.push_back(upper);
119
2
        buffer.push_back(lower);
120
2
        return *this;
121
2
    }
122
123
    Serialization &Serialization::SerializeU32(uint32_t num)
124
20
    {
125
20
        uint8_t b1 = (num & 0xFF);
126
20
        uint8_t b2 = (num >> 8) & 0xFF;
127
20
        uint8_t b3 = (num >> 16) & 0xFF;
128
20
        uint8_t b4 = (num >> 24) & 0xFF;
129
20
        buffer.push_back(b1);
130
20
        buffer.push_back(b2);
131
20
        buffer.push_back(b3);
132
20
        buffer.push_back(b4);
133
20
        return *this;
134
20
    }
135
136
    Serialization &Serialization::SerializeU64(uint64_t num)
137
94
    {
138
94
        uint8_t b1 = num & 0xFF;
139
94
        uint8_t b2 = (num >> 8) & 0xFF;
140
94
        uint8_t b3 = (num >> 16) & 0xFF;
141
94
        uint8_t b4 = (num >> 24) & 0xFF;
142
94
        uint8_t b5 = (num >> 32) & 0xFF;
143
94
        uint8_t b6 = (num >> 40) & 0xFF;
144
94
        uint8_t b7 = (num >> 48) & 0xFF;
145
94
        uint8_t b8 = (num >> 56) & 0xFF;
146
94
        buffer.push_back(b1);
147
94
        buffer.push_back(b2);
148
94
        buffer.push_back(b3);
149
94
        buffer.push_back(b4);
150
94
        buffer.push_back(b5);
151
94
        buffer.push_back(b6);
152
94
        buffer.push_back(b7);
153
94
        buffer.push_back(b8);
154
94
        return *this;
155
94
    }
156
157
    Serialization &Serialization::SerializeU128(CryptoPP::Integer num)
158
8
    {
159
8
        std::vector<uint8_t> content(16, 0); // Initialize with 16 zero bytes
160
161
8
        num.Encode(content.data(), 16);
162
163
        // convert from big endian to little endian
164
8
        std::reverse(content.begin(), content.end());
165
166
8
        buffer.insert(buffer.end(), content.begin(), content.end());
167
168
8
        return *this;
169
8
    }
170
171
    Serialization &Serialization::SerializeU256(CryptoPP::Integer num)
172
1
    {
173
1
        std::vector<uint8_t> content(32, 0); // Initialize with 16 zero bytes
174
175
1
        num.Encode(content.data(), 32);
176
177
        // convert from big endian to little endian
178
1
        std::reverse(content.begin(), content.end());
179
180
1
        buffer.insert(buffer.end(), content.begin(), content.end());
181
182
1
        return *this;
183
1
    }
184
185
    Serialization &Serialization::Serialize(std::vector<std::shared_ptr<ISerializable>> args)
186
4
    {
187
4
        SerializeU32AsUleb128(static_cast<uint32_t>(args.size()));
188
4
        for (auto &element : args)
189
14
        {
190
14
            Serialization s;
191
14
            element->Serialize(s);
192
14
            std::vector<uint8_t> b = s.GetBytes();
193
14
            SerializeFixedBytes(b);
194
14
        }
195
4
        return *this;
196
4
    }
197
198
    Serialization &Serialization::Serialize(const Sequence &args)
199
62
    {
200
62
        auto vl = args.getValues();
201
62
        SerializeU32AsUleb128(static_cast<uint32_t>(vl.size()));
202
62
        for (auto &element : vl)
203
119
        {
204
119
            Serialization s;
205
119
            element->Serialize(s);
206
119
            std::vector<uint8_t> b = s.GetBytes();
207
119
            SerializeFixedBytes(b);
208
119
        }
209
62
        return *this;
210
62
    }
211
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/SignedTransaction.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "SignedTransaction.h"
2
#include "MultiAgentRawTransaction.h"
3
#include "../HDWallet/Utils/Utils.h"
4
5
namespace Aptos::BCS
6
{
7
    SignedTransaction::SignedTransaction(const RawTransaction &transaction, const Authenticator &authenticator)
8
3
        : transaction(transaction), authenticator(authenticator) {}
9
10
    std::vector<uint8_t> SignedTransaction::Bytes() const
11
0
    {
12
0
        Serialization ser;
13
0
        ser.Serialize(*this);
14
0
        return ser.GetBytes();
15
0
    }
16
17
    bool SignedTransaction::Verify()
18
3
    {
19
3
        std::vector<uint8_t> keyed;
20
21
3
        if (std::dynamic_pointer_cast<MultiAgentAuthenticator>(authenticator.GetAuthenticator()) != nullptr)
22
2
        {
23
2
            const std::shared_ptr<MultiAgentAuthenticator> multiAgentAuthenticator = std::dynamic_pointer_cast<MultiAgentAuthenticator>(authenticator.GetAuthenticator());
24
25
2
            MultiAgentRawTransaction transaction(this->transaction, multiAgentAuthenticator->SecondaryAddresses());
26
27
2
            keyed = transaction.Keyed();
28
2
        }
29
1
        else
30
1
        {
31
1
            keyed = this->transaction.Keyed();
32
1
        }
33
34
3
        return authenticator.Verify(Utils::ByteVectorToSecBlock(keyed));
35
3
    }
36
37
    void SignedTransaction::Serialize(Serialization &serializer) const
38
2
    {
39
2
        transaction.Serialize(serializer);
40
2
        authenticator.Serialize(serializer);
41
2
    }
42
43
    std::shared_ptr<ISerializable> SignedTransaction::Deserialize(Deserialization &deserializer)
44
1
    {
45
1
        auto transaction = std::dynamic_pointer_cast<RawTransaction>(RawTransaction::Deserialize(deserializer));
46
1
        auto authenticator = std::dynamic_pointer_cast<Authenticator>(Authenticator::Deserialize(deserializer));
47
1
        return std::make_shared<SignedTransaction>(*transaction, *authenticator);
48
1
    }
49
50
    bool SignedTransaction::Equals(const SignedTransaction &other) const
51
1
    {
52
1
        return transaction.Equals(other.transaction) && authenticator.Equals(other.authenticator);
53
1
    }
54
55
    std::string SignedTransaction::ToString() const
56
0
    {
57
0
        return "Transaction: " + transaction.ToString() + "\n Authenticator: " + authenticator.ToString();
58
0
    }
59
60
    size_t SignedTransaction::GetHashCode()
61
0
    {
62
0
        size_t hash = 17;
63
0
        hash = hash * 23 + transaction.GetHashCode();
64
0
        hash = hash * 23 + authenticator.GetHashCode();
65
0
        return hash;
66
0
    }
67
68
    RawTransaction SignedTransaction::getTransaction() const
69
1
    {
70
1
        return transaction;
71
1
    }
72
73
    bool operator==(const SignedTransaction &lhs, const SignedTransaction &rhs)
74
1
    {
75
1
        return lhs.Equals(rhs);
76
1
    }
77
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/StructTag.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "StructTag.h"
2
3
namespace Aptos::BCS
4
{
5
    StructTag::StructTag(AccountAddress address, std::string module, std::string name,
6
                         const std::vector<std::shared_ptr<ISerializableTag>> &typeArgs)
7
22
        : address(address), module(module), name(name), typeArgs(typeArgs) {}
8
9
20
    TypeTag StructTag::Variant() const { return TypeTag::STRUCT; }
10
11
    void StructTag::Serialize(Serialization &serializer) const
12
20
    {
13
20
        serializer.SerializeU32AsUleb128(static_cast<uint32_t>(Variant()));
14
20
        address.Serialize(serializer);
15
20
        serializer.Serialize(module);
16
20
        serializer.Serialize(name);
17
20
        serializer.SerializeU32AsUleb128(static_cast<uint32_t>(typeArgs.size()));
18
19
20
        for (auto typeArg : typeArgs)
20
0
        {
21
0
            typeArg->Serialize(serializer);
22
0
        }
23
20
    }
24
25
    std::shared_ptr<ISerializableTag> StructTag::Deserialize(Deserialization &deserializer)
26
2
    {
27
2
        auto address = std::dynamic_pointer_cast<AccountAddress>(AccountAddress::Deserialize(deserializer));
28
2
        std::string module = deserializer.DeserializeString();
29
2
        std::string name = deserializer.DeserializeString();
30
31
2
        uint32_t length = deserializer.DeserializeUleb128();
32
2
        std::vector<std::shared_ptr<ISerializableTag>> typeArgsList;
33
34
2
        while (typeArgsList.size() < length)
35
0
        {
36
0
            std::shared_ptr<ISerializableTag> val = ISerializableTag::DeserializeTag(deserializer);
37
0
            typeArgsList.push_back(val);
38
0
        }
39
40
2
        return std::make_shared<StructTag>(*address, module, name, typeArgsList);
41
2
    }
42
43
    bool StructTag::Equals(const StructTag &other) const
44
2
    {
45
2
        return (address == other.address &&
46
2
                module == other.module &&
47
2
                name == other.name &&
48
2
                typeArgs == other.typeArgs);
49
2
    }
50
51
    std::string StructTag::ToString() const
52
5
    {
53
5
        std::string value = address.ToString() + "::" + module + "::" + name;
54
55
5
        if (!typeArgs.empty())
56
0
        {
57
0
            value += "<" + typeArgs[0]->ToString();
58
0
            for (size_t i = 1; i < typeArgs.size(); ++i)
59
0
            {
60
0
                value += ", " + typeArgs[i]->ToString();
61
0
            }
62
0
            value += ">";
63
0
        }
64
65
5
        return value;
66
5
    }
67
68
    StructTag StructTag::FromStr(const std::string &typeTag)
69
2
    {
70
2
        std::string name;
71
2
        int index = 0;
72
54
        while (index < typeTag.length())
73
52
        {
74
52
            char letter = typeTag[index];
75
52
            index += 1;
76
77
52
            if (letter == '<')
78
0
            {
79
0
                throw std::runtime_error("Parsing type arguments is not implemented yet");
80
0
            }
81
52
            else
82
52
            {
83
52
                name += letter;
84
52
            }
85
52
        }
86
87
        // Split the name into parts using "::" as the delimiter
88
2
        size_t pos = 0;
89
2
        std::vector<std::string> split;
90
6
        while ((pos = name.find("::")) != std::string::npos)
91
4
        {
92
4
            split.push_back(name.substr(0, pos));
93
4
            name.erase(0, pos + 2); // +2 to skip the "::" itself
94
4
        }
95
2
        split.push_back(name); // Add the final part
96
97
2
        if (split.size() < 3)
98
0
        {
99
0
            throw std::runtime_error("Invalid typeTag format");
100
0
        }
101
102
2
        return StructTag(AccountAddress::FromHex(split[0]), split[1], split[2], {});
103
2
    }
104
105
    bool operator==(const StructTag &lhs, const StructTag &rhs)
106
2
    {
107
2
        return lhs.Equals(rhs);
108
2
    }
109
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/TagSequence.cpp
Line
Count
Source
1
#include "TagSequence.h"
2
#include <vector>
3
#include "Serialization.h"
4
#include "Deserialization.h"
5
#include <sstream>
6
7
namespace Aptos::BCS
8
{
9
    TagSequence::TagSequence(const std::vector<std::shared_ptr<ISerializableTag>> &serializableTags)
10
37
    {
11
37
        this->serializableTags = serializableTags;
12
37
    }
13
14
    void TagSequence::Serialize(Serialization &serializer) const
15
54
    {
16
54
        serializer.SerializeU32AsUleb128(this->serializableTags.size());
17
54
        for (const auto &element : this->serializableTags)
18
20
        {
19
20
            element->Serialize(serializer);
20
20
        }
21
54
    }
22
23
    std::shared_ptr<ISerializable> TagSequence::Deserialize(Deserialization &deserializer)
24
1
    {
25
1
        int length = deserializer.DeserializeUleb128();
26
27
1
        std::vector<std::shared_ptr<ISerializableTag>> values;
28
29
2
        while (values.size() < length)
30
1
        {
31
1
            auto tag = ISerializableTag::DeserializeTag(deserializer);
32
1
            values.push_back(std::dynamic_pointer_cast<ISerializableTag>(tag));
33
1
        }
34
35
1
        return std::make_shared<TagSequence>(values);
36
1
    }
37
38
    std::vector<std::shared_ptr<ISerializableTag>> TagSequence::GetValue() const
39
1
    {
40
1
        return serializableTags;
41
1
    }
42
43
    bool TagSequence::Equals(const TagSequence &other) const
44
10
    {
45
10
        Serialization s1;
46
10
        this->Serialize(s1);
47
10
        Serialization s2;
48
10
        other.Serialize(s2);
49
10
        return s1.GetBytes() == s2.GetBytes();
50
10
    }
51
52
    std::string TagSequence::ToString() const
53
3
    {
54
3
        std::ostringstream oss;
55
3
        for (const auto &tag : this->serializableTags)
56
3
        {
57
3
            oss << tag->ToString();
58
3
        }
59
3
        return oss.str();
60
3
    }
61
62
    size_t TagSequence::GetHashCode() const
63
2
    {
64
2
        return 0;
65
2
    }
66
67
    bool operator==(const TagSequence &lhs, const TagSequence &rhs)
68
1
    {
69
1
        return lhs.Equals(rhs);
70
1
    }
71
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/TransactionPayload.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "TransactionPayload.h"
2
#include "Script.h"
3
#include "EntryFunction.h"
4
5
namespace Aptos::BCS
6
{
7
    TransactionPayload::TransactionPayload(const std::shared_ptr<ISerializable> &payload)
8
15
    {
9
15
        if (std::dynamic_pointer_cast<Script>(payload))
10
0
        {
11
0
            this->variant = TransactionPayloadTypeTag::SCRIPT;
12
0
        }
13
15
        else if (std::dynamic_pointer_cast<EntryFunction>(payload))
14
15
        {
15
15
            this->variant = TransactionPayloadTypeTag::SCRIPT_FUNCTION;
16
15
        }
17
0
        else
18
0
        {
19
0
            throw std::invalid_argument("Invalid type");
20
0
        }
21
22
15
        this->value = payload;
23
15
    }
24
25
    TransactionPayloadTypeTag TransactionPayload::Variant() const
26
16
    {
27
16
        return this->variant;
28
16
    }
29
30
    void TransactionPayload::Serialize(Serialization &serializer) const
31
16
    {
32
16
        serializer.SerializeU32AsUleb128(static_cast<uint32_t>(this->Variant()));
33
16
        this->value->Serialize(serializer);
34
16
    }
35
36
    std::shared_ptr<ISerializable> TransactionPayload::Deserialize(Deserialization &deserializer)
37
3
    {
38
3
        TransactionPayloadTypeTag variant = static_cast<TransactionPayloadTypeTag>(deserializer.DeserializeUleb128());
39
3
        std::shared_ptr<ISerializable> payload = nullptr;
40
3
        if (variant == TransactionPayloadTypeTag::SCRIPT)
41
0
        {
42
0
            payload = Script::Deserialize(deserializer);
43
0
        }
44
3
        else if (variant == TransactionPayloadTypeTag::SCRIPT_FUNCTION)
45
3
        {
46
3
            payload = EntryFunction::Deserialize(deserializer);
47
3
        }
48
0
        else
49
0
        {
50
0
            throw std::invalid_argument("Invalid type " + std::to_string(static_cast<int>(variant)));
51
0
        }
52
53
3
        return std::make_shared<TransactionPayload>(payload);
54
3
    }
55
56
    bool TransactionPayload::Equals(const TransactionPayload &other) const
57
6
    {
58
6
        bool variantComparison = this->variant == other.variant;
59
6
        bool txnPayload = false;
60
6
        if (variantComparison)
61
6
        {
62
6
            auto script = std::dynamic_pointer_cast<Script>(value);
63
6
            if (script)
64
0
            {
65
0
                txnPayload = script->Equals(*(std::dynamic_pointer_cast<Script>(other.value)));
66
0
            }
67
6
            else
68
6
            {
69
6
                auto func = std::dynamic_pointer_cast<EntryFunction>(value);
70
6
                if (func)
71
6
                {
72
6
                    txnPayload = func->Equals(*(std::dynamic_pointer_cast<EntryFunction>(other.value)));
73
6
                }
74
0
                else
75
0
                {
76
0
                    txnPayload = false;
77
0
                }
78
6
            }
79
6
        }
80
0
        else
81
0
        {
82
0
            return false;
83
0
        }
84
6
        return variantComparison && txnPayload;
85
6
    }
86
87
    std::string TransactionPayload::ToString() const
88
1
    {
89
1
        return this->value->ToString();
90
1
    }
91
92
    size_t TransactionPayload::GetHashCode()
93
2
    {
94
2
        size_t hash = 17;
95
2
        hash = hash * 23 + this->value->GetHashCode();
96
2
        hash = hash * 23 + static_cast<size_t>(this->variant);
97
2
        return hash;
98
2
    }
99
100
    bool operator==(const TransactionPayload &lhs, const TransactionPayload &rhs)
101
4
    {
102
4
        return lhs.Equals(rhs);
103
4
    }
104
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/U128.cpp
Line
Count
Source
1
#include "U128.h"
2
#include "Serialization.h"
3
#include "Deserialization.h"
4
#include <cryptopp/sha.h>     // for SHA256
5
#include <cryptopp/hex.h>     // for StringSource and HexEncoder
6
#include <cryptopp/filters.h> // for StringSink
7
#include <cryptopp/cryptlib.h>
8
#include <sstream>
9
10
using namespace CryptoPP;
11
namespace Aptos::BCS
12
{
13
    U128::U128(CryptoPP::Integer value)
14
9
    {
15
9
        this->value = value;
16
9
    }
17
18
    void U128::Serialize(Serialization &serializer) const
19
1
    {
20
1
        serializer.SerializeU128(value);
21
1
    }
22
23
    std::shared_ptr<ISerializableTag> U128::Deserialize(Deserialization &deserializer)
24
1
    {
25
1
        CryptoPP::Integer value = deserializer.DeserializeU128();
26
1
        return std::make_shared<U128>(value);
27
1
    }
28
29
    std::string U128::ToString() const
30
2
    {
31
2
        std::ostringstream oss;
32
2
        oss << this->value;
33
2
        return oss.str();
34
2
    }
35
36
    bool U128::Equals(const U128 &other) const
37
2
    {
38
2
        return this->value == other.value;
39
2
    }
40
41
    size_t U128::GetHashCode() const
42
1
    {
43
1
        byte digest[CryptoPP::SHA256::DIGESTSIZE];
44
1
        std::string strValue = this->ToString();
45
46
1
        CryptoPP::SHA256().CalculateDigest(digest, (byte *)strValue.c_str(), strValue.length());
47
48
        // Convert the hash to a string
49
1
        CryptoPP::HexEncoder encoder;
50
1
        std::string output;
51
1
        encoder.Attach(new CryptoPP::StringSink(output));
52
1
        encoder.Put(digest, sizeof(digest));
53
1
        encoder.MessageEnd();
54
55
        // Use std::hash to convert the hash string to a size_t
56
1
        return std::hash<std::string>{}(output);
57
1
    }
58
59
    CryptoPP::Integer U128::Deserialize(const std::vector<uint8_t> &data)
60
6
    {
61
6
        if (data.size() < 16)
62
1
        {
63
1
            throw std::runtime_error("Not enough bytes to deserialize a CryptoPP::Integer");
64
1
        }
65
        // Convert bytes to CryptoPP::Integer
66
5
        CryptoPP::Integer res(data.data(), 16, CryptoPP::Integer::UNSIGNED, LITTLE_ENDIAN_ORDER);
67
5
        return res;
68
6
    }
69
70
    TypeTag U128::Variant() const
71
2
    {
72
2
        return TypeTag::U128;
73
2
    }
74
75
    CryptoPP::Integer U128::GetValue() const
76
2
    {
77
2
        return this->value;
78
2
    }
79
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/U16.cpp
Line
Count
Source
1
#include "U16.h"
2
#include "Serialization.h"
3
#include "Deserialization.h"
4
#include <boost/endian/conversion.hpp>
5
#include <sstream>
6
7
namespace Aptos::BCS
8
{
9
    U16::U16(uint16_t value)
10
9
    {
11
9
        this->value = value;
12
9
    }
13
14
    void U16::Serialize(Serialization &serializer) const
15
1
    {
16
1
        serializer.SerializeU16(this->value);
17
1
    }
18
19
    std::shared_ptr<ISerializableTag> U16::Deserialize(Deserialization &deserializer)
20
1
    {
21
1
        uint16_t value = deserializer.DeserializeU16();
22
1
        return std::make_shared<U16>(value);
23
1
    }
24
25
    TypeTag U16::Variant() const
26
2
    {
27
2
        return TypeTag::U16;
28
2
    }
29
30
    uint16_t U16::GetValue() const
31
2
    {
32
2
        return value;
33
2
    }
34
35
    bool U16::Equals(const U16 &other) const
36
2
    {
37
2
        return this->value == other.value;
38
2
    }
39
40
    std::string U16::ToString() const
41
1
    {
42
1
        std::ostringstream oss;
43
1
        oss << static_cast<int>(this->value);
44
1
        return oss.str();
45
1
    }
46
47
    size_t U16::GetHashCode() const
48
1
    {
49
        // Simple hash code calculation, more sophisticated method might be needed
50
1
        return std::hash<uint16_t>{}(this->value);
51
1
    }
52
53
    uint16_t U16::Deserialize(const std::vector<uint8_t> &data)
54
4
    {
55
4
        if (data.size() < sizeof(uint16_t))
56
1
        {
57
1
            throw std::runtime_error("Not enough bytes to deserialize a uint16_t");
58
1
        }
59
60
3
        uint16_t res;
61
3
        std::memcpy(&res, data.data(), sizeof(uint16_t));
62
3
        return boost::endian::little_to_native(res);
63
4
    }
64
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/U256.cpp
Line
Count
Source
1
#include "U256.h"
2
#include "Serialization.h"
3
#include "Deserialization.h"
4
#include <cryptopp/sha.h>     // for SHA256
5
#include <cryptopp/hex.h>     // for StringSource and HexEncoder
6
#include <cryptopp/filters.h> // for StringSink
7
#include <cryptopp/cryptlib.h>
8
#include <sstream>
9
10
using namespace CryptoPP;
11
namespace Aptos::BCS
12
{
13
    U256::U256(CryptoPP::Integer value)
14
9
    {
15
9
        this->value = value;
16
9
    }
17
18
    void U256::Serialize(Serialization &serializer) const
19
1
    {
20
1
        serializer.SerializeU128(value);
21
1
    }
22
23
    std::shared_ptr<ISerializableTag> U256::Deserialize(Deserialization &deserializer)
24
1
    {
25
1
        CryptoPP::Integer value = deserializer.DeserializeU128();
26
1
        return std::make_shared<U256>(value);
27
1
    }
28
29
    std::string U256::ToString() const
30
2
    {
31
2
        std::ostringstream oss;
32
2
        oss << this->value;
33
2
        return oss.str();
34
2
    }
35
36
    bool U256::Equals(const U256 &other) const
37
2
    {
38
2
        return this->value == other.value;
39
2
    }
40
41
    size_t U256::GetHashCode() const
42
1
    {
43
1
        byte digest[CryptoPP::SHA256::DIGESTSIZE];
44
1
        std::string strValue = this->ToString();
45
46
1
        CryptoPP::SHA256().CalculateDigest(digest, (byte *)strValue.c_str(), strValue.length());
47
48
        // Convert the hash to a string
49
1
        CryptoPP::HexEncoder encoder;
50
1
        std::string output;
51
1
        encoder.Attach(new CryptoPP::StringSink(output));
52
1
        encoder.Put(digest, sizeof(digest));
53
1
        encoder.MessageEnd();
54
55
        // Use std::hash to convert the hash string to a size_t
56
1
        return std::hash<std::string>{}(output);
57
1
    }
58
59
    CryptoPP::Integer U256::Deserialize(const std::vector<uint8_t> &data)
60
3
    {
61
3
        if (data.size() < 32)
62
1
        {
63
1
            throw std::runtime_error("Not enough bytes to deserialize a CryptoPP::Integer");
64
1
        }
65
        // Convert bytes to CryptoPP::Integer
66
2
        CryptoPP::Integer res(data.data(), 16, CryptoPP::Integer::UNSIGNED, LITTLE_ENDIAN_ORDER);
67
2
        return res;
68
3
    }
69
70
    TypeTag U256::Variant() const
71
2
    {
72
2
        return TypeTag::U256;
73
2
    }
74
75
    Integer U256::GetValue() const
76
2
    {
77
2
        return value;
78
2
    }
79
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/U32.cpp
Line
Count
Source
1
#include "U32.h"
2
#include "Serialization.h"
3
#include "Deserialization.h"
4
#include <boost/endian/conversion.hpp>
5
#include <sstream>
6
7
namespace Aptos::BCS
8
{
9
    U32::U32(uint32_t value)
10
29
    {
11
29
        this->value = value;
12
29
    }
13
14
    void U32::Serialize(Serialization &serializer) const
15
15
    {
16
15
        serializer.SerializeU32(this->value);
17
15
    }
18
19
    std::shared_ptr<ISerializableTag> U32::Deserialize(Deserialization &deserializer)
20
4
    {
21
4
        uint32_t value = deserializer.DeserializeU32();
22
4
        return std::make_shared<U32>(value);
23
4
    }
24
25
    TypeTag U32::Variant() const
26
2
    {
27
2
        return TypeTag::U32;
28
2
    }
29
30
    uint32_t U32::GetValue() const
31
2
    {
32
2
        return value;
33
2
    }
34
35
    bool U32::Equals(const U32 &other) const
36
5
    {
37
5
        return this->value == other.value;
38
5
    }
39
40
    std::string U32::ToString() const
41
1
    {
42
1
        std::ostringstream oss;
43
1
        oss << static_cast<int>(this->value);
44
1
        return oss.str();
45
1
    }
46
47
    size_t U32::GetHashCode() const
48
2
    {
49
        // Simple hash code calculation, more sophisticated method might be needed
50
2
        return std::hash<uint32_t>{}(this->value);
51
2
    }
52
53
    uint32_t U32::Deserialize(const std::vector<uint8_t> &data)
54
7
    {
55
7
        if (data.size() < sizeof(uint32_t))
56
1
        {
57
1
            throw std::runtime_error("Not enough bytes to deserialize a uint32_t");
58
1
        }
59
60
6
        uint32_t res;
61
6
        std::memcpy(&res, data.data(), sizeof(uint32_t));
62
6
        return boost::endian::little_to_native(res);
63
7
    }
64
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/U64.cpp
Line
Count
Source
1
#include "U64.h"
2
#include "Serialization.h"
3
#include "Deserialization.h"
4
#include <boost/endian/conversion.hpp>
5
#include <sstream>
6
7
namespace Aptos::BCS
8
{
9
    U64::U64(uint64_t value)
10
32
    {
11
32
        this->value = value;
12
32
    }
13
14
    void U64::Serialize(Serialization &serializer) const
15
21
    {
16
21
        serializer.SerializeU64(this->value);
17
21
    }
18
19
    std::shared_ptr<ISerializableTag> U64::Deserialize(Deserialization &deserializer)
20
1
    {
21
1
        uint64_t value = deserializer.DeserializeU64();
22
1
        return std::make_shared<U64>(value);
23
1
    }
24
25
    TypeTag U64::Variant() const
26
2
    {
27
2
        return TypeTag::U64;
28
2
    }
29
30
    uint64_t U64::GetValue() const
31
11
    {
32
11
        return value;
33
11
    }
34
35
    bool U64::Equals(const U64 &other) const
36
2
    {
37
2
        return this->value == other.value;
38
2
    }
39
40
    std::string U64::ToString() const
41
2
    {
42
2
        std::ostringstream oss;
43
2
        oss << static_cast<int>(this->value);
44
2
        return oss.str();
45
2
    }
46
47
    size_t U64::GetHashCode() const
48
1
    {
49
        // Simple hash code calculation, more sophisticated method might be needed
50
1
        return std::hash<uint64_t>{}(this->value);
51
1
    }
52
53
    uint64_t U64::Deserialize(const std::vector<uint8_t> &data)
54
19
    {
55
19
        if (data.size() < sizeof(uint64_t))
56
1
        {
57
1
            throw std::runtime_error("Not enough bytes to deserialize a uint64_t");
58
1
        }
59
60
18
        uint64_t res;
61
18
        std::memcpy(&res, data.data(), sizeof(uint64_t));
62
18
        return boost::endian::little_to_native(res);
63
19
    }
64
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/U8.cpp
Line
Count
Source
1
#include "U8.h"
2
#include "Serialization.h"
3
#include "Deserialization.h"
4
#include <sstream>
5
6
namespace Aptos::BCS
7
{
8
    U8::U8(uint8_t value)
9
12
    {
10
12
        this->value = value;
11
12
    }
12
13
    void U8::Serialize(Serialization &serializer) const
14
1
    {
15
1
        serializer.SerializeU8(this->value);
16
1
    }
17
18
    std::shared_ptr<ISerializableTag> U8::Deserialize(Deserialization &deserializer)
19
2
    {
20
2
        uint8_t value = deserializer.DeserializeU8();
21
2
        return std::make_shared<U8>(value);
22
2
    }
23
24
    TypeTag U8::Variant() const
25
2
    {
26
2
        return TypeTag::U8;
27
2
    }
28
29
    uint8_t U8::GetValue() const
30
2
    {
31
2
        return value;
32
2
    }
33
34
    bool U8::Equals(const U8 &other) const
35
2
    {
36
2
        return this->value == other.value;
37
2
    }
38
39
    std::string U8::ToString() const
40
1
    {
41
1
        std::ostringstream oss;
42
1
        oss << static_cast<int>(this->value);
43
1
        return oss.str();
44
1
    }
45
46
    size_t U8::GetHashCode() const
47
4
    {
48
        // Simple hash code calculation, more sophisticated method might be needed
49
4
        return std::hash<uint8_t>{}(this->value);
50
4
    }
51
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/BCS/rawtransaction.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "rawtransaction.h"
2
#include <stdexcept>
3
#include <cryptopp/sha3.h>
4
#include <cryptopp/filters.h>
5
#include <cryptopp/hex.h>
6
#include "../HDWallet/Utils/Utils.h"
7
8
using namespace Aptos::Accounts;
9
namespace Aptos::BCS
10
{
11
    RawTransaction::RawTransaction(const AccountAddress &sender, int sequenceNumber, const TransactionPayload &payload, int maxGasAmount, int gasUnitPrice, uint64_t expirationTimestampsSecs, int chainId)
12
        : sender(sender), sequenceNumber(sequenceNumber), payload(payload),
13
          maxGasAmount(maxGasAmount), gasUnitPrice(gasUnitPrice),
14
          expirationTimestampsSecs(expirationTimestampsSecs), chainId(chainId)
15
8
    {
16
8
    }
17
18
    std::vector<uint8_t> RawTransaction::Prehash()
19
5
    {
20
5
        CryptoPP::SHA3_256 sha3;
21
5
        std::string input = "APTOS::RawTransaction";
22
5
        auto inputS = Utils::StringToSecByteBlock(input.data());
23
5
        sha3.Update(inputS, inputS.size());
24
5
        CryptoPP::SecByteBlock result(Utils::Ed25519PublicKeySizeInBytes); // 256 bits = 32 bytes
25
5
        sha3.Final(result);
26
27
5
        return Utils::SecBlockToByteVector(result);
28
5
    }
29
30
    std::vector<uint8_t> RawTransaction::Keyed()
31
4
    {
32
4
        Serialization ser;
33
4
        this->Serialize(ser);
34
35
4
        std::vector<uint8_t> prehash = this->Prehash();
36
4
        std::vector<uint8_t> outputBytes = ser.GetBytes();
37
38
4
        std::vector<uint8_t> res(prehash.size() + outputBytes.size());
39
4
        std::copy(prehash.begin(), prehash.end(), res.begin());
40
4
        std::copy(outputBytes.begin(), outputBytes.end(), res.begin() + prehash.size());
41
42
4
        return res;
43
4
    }
44
45
    Signature RawTransaction::Sign(PrivateKey key)
46
1
    {
47
1
        return key.Sign(Utils::ByteVectorToSecBlock(this->Keyed()));
48
1
    }
49
50
    bool RawTransaction::Verify(PublicKey key, const Signature &signature)
51
1
    {
52
1
        return key.Verify(Utils::ByteVectorToSecBlock(Keyed()), signature);
53
1
    }
54
55
    void RawTransaction::Serialize(Serialization &serializer) const
56
15
    {
57
15
        this->sender.Serialize(serializer);
58
15
        serializer.SerializeU64(static_cast<uint64_t>(this->sequenceNumber));
59
15
        this->payload.Serialize(serializer);
60
15
        serializer.SerializeU64(static_cast<uint64_t>(this->maxGasAmount));
61
15
        serializer.SerializeU64(static_cast<uint64_t>(this->gasUnitPrice));
62
15
        serializer.SerializeU64(static_cast<uint64_t>(this->expirationTimestampsSecs));
63
15
        serializer.SerializeU8(static_cast<uint8_t>(this->chainId));
64
15
    }
65
66
    std::shared_ptr<ISerializable> RawTransaction::Deserialize(Deserialization &deserializer)
67
3
    {
68
3
        auto sender = std::dynamic_pointer_cast<AccountAddress>(AccountAddress::Deserialize(deserializer));
69
3
        auto sequenceNumber = deserializer.DeserializeU64();
70
3
        auto payload = std::dynamic_pointer_cast<TransactionPayload>(TransactionPayload::Deserialize(deserializer));
71
3
        auto maxGasAmount = deserializer.DeserializeU64();
72
3
        auto gasUnitPrice = deserializer.DeserializeU64();
73
3
        auto expirationTimestampsSecs = deserializer.DeserializeU64();
74
3
        auto chainId = deserializer.DeserializeU8();
75
76
3
        return std::make_shared<RawTransaction>(
77
3
            *sender,
78
3
            static_cast<int>(sequenceNumber),
79
3
            *payload,
80
3
            static_cast<int>(maxGasAmount),
81
3
            static_cast<int>(gasUnitPrice),
82
3
            static_cast<int>(expirationTimestampsSecs),
83
3
            static_cast<int>(chainId));
84
3
    }
85
86
    std::string RawTransaction::ToString() const
87
0
    {
88
0
        return "RawTransaction";
89
0
    }
90
91
    bool RawTransaction::Equals(const RawTransaction &other) const
92
4
    {
93
4
        return (
94
4
            this->sender == other.sender &&
95
4
            this->sequenceNumber == other.sequenceNumber &&
96
4
            this->payload == other.payload &&
97
4
            this->maxGasAmount == other.maxGasAmount &&
98
4
            this->gasUnitPrice == other.gasUnitPrice &&
99
4
            this->expirationTimestampsSecs == other.expirationTimestampsSecs &&
100
4
            this->chainId == other.chainId);
101
4
    }
102
103
    bool operator==(const RawTransaction &lhs, const RawTransaction &rhs)
104
3
    {
105
3
        return lhs.Equals(rhs);
106
3
    }
107
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/HDWallet/Utils/Utils.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "Utils.h"
2
#include <algorithm>
3
#include <cryptopp/sha.h>
4
#include <cryptopp/filters.h>
5
#include <cryptopp/hex.h>
6
#include <cryptopp/xed25519.h>
7
#include <sstream>
8
#include <iomanip>
9
#include "../../Accounts/PrivateKey.h"
10
11
using namespace Aptos::Accounts;
12
namespace Aptos::Utils
13
{
14
    bool IsValidAddress(std::string walletAddress)
15
49
    {
16
49
        if (walletAddress.substr(0, 2) == "0x")
17
28
            walletAddress = walletAddress.substr(2);
18
19
49
        std::regex pattern("[a-fA-F0-9]{64}$");
20
49
        return std::regex_match(walletAddress, pattern);
21
49
    }
22
23
    std::vector<uint8_t> ByteArrayFromHexString(std::string input)
24
2
    {
25
2
        if (input.substr(0, 2) == "0x")
26
0
            input = input.substr(2);
27
28
2
        size_t outputLength = input.length() / 2;
29
2
        std::vector<uint8_t> output(outputLength);
30
31
635
        for (int i = 0; i < outputLength; i++)
32
633
            output[i] = std::stoi(input.substr(i * 2, 2), nullptr, 16);
33
34
2
        return output;
35
2
    }
36
37
    std::string HexStringFromByteArray(const std::vector<uint8_t> &input)
38
5
    {
39
5
        std::string output;
40
5
        for (const auto &byte : input)
41
834
        {
42
834
            char buf[3];
43
834
            snprintf(buf, sizeof(buf), "%02x", byte);
44
834
            output += buf;
45
834
        }
46
5
        return output;
47
5
    }
48
49
    template <typename TKey, typename TValue>
50
    void addOrReplace(std::map<TKey, TValue> &dictionary, TKey key,
51
                      TValue value)
52
    {
53
        dictionary[key] =
54
            value;
55
    }
56
57
    template <typename TKey, typename TValue>
58
    TValue TryGet(const std::map<TKey, TValue> &dictionary, TKey key)
59
    {
60
        auto it = dictionary.find(key);
61
        if (it != dictionary.end())
62
            return it->second;
63
        else
64
            return TValue(); // Or whatever default value you want
65
    }
66
67
    template <typename T>
68
    std::vector<T> Slice(std::vector<T> source, int start, int end)
69
    {
70
        if (end < 0)
71
            end = source.size();
72
73
        int len = end - start;
74
75
        std::vector<T> res(source.begin() + start, source.begin() + end);
76
        return res;
77
    }
78
79
    template <typename T>
80
    std::vector<T> Slice(std::vector<T> source, int start)
81
    {
82
        return Slice(source, start, -1);
83
    }
84
85
    std::vector<uint8_t> Sha256(const std::vector<uint8_t> &data, int offset, int count)
86
0
    {
87
0
        CryptoPP::SHA256 hash;
88
0
        std::vector<uint8_t> digest(hash.DigestSize());
89
90
0
        std::string message(data.begin() + offset, data.begin() + offset + count);
91
0
        hash.CalculateDigest(digest.data(), (unsigned char *)message.data(), message.size());
92
93
0
        return digest;
94
0
    }
95
96
    std::vector<uint8_t> Sha256(const std::vector<uint8_t> &data)
97
0
    {
98
0
        return Sha256(data, 0, data.size());
99
0
    }
100
101
    std::pair<CryptoPP::SecByteBlock, CryptoPP::SecByteBlock> EdKeyPairFromSeed(const CryptoPP::SecByteBlock &seed)
102
3
    {
103
3
        PrivateKey priv(seed);
104
3
        auto pub = priv.GetPublicKey();
105
3
        return {seed, pub.KeyBytes()};
106
3
    }
107
108
    CryptoPP::SecByteBlock ByteVectorToSecBlock(const std::vector<uint8_t> &input)
109
159
    {
110
159
        CryptoPP::SecByteBlock output(input.data(), input.size());
111
159
        return output;
112
159
    }
113
114
    std::vector<uint8_t> SecBlockToByteVector(const CryptoPP::SecByteBlock &input)
115
152
    {
116
152
        std::vector<uint8_t> byteArray(input.data(), input.data() + input.size());
117
152
        return byteArray;
118
152
    }
119
120
    CryptoPP::SecByteBlock StringToSecByteBlock(const std::string &str)
121
20
    {
122
20
        CryptoPP::SecByteBlock secBlock(str.size());
123
20
        std::memcpy(secBlock.BytePtr(), str.c_str(), str.size());
124
20
        return secBlock;
125
20
    }
126
127
    std::string ltrim(const std::string &s, const std::string &charsToTrim)
128
5
    {
129
5
        auto it = std::find_if(s.begin(), s.end(), [charsToTrim](char c)
130
19
                               { return charsToTrim.find(c) == std::string::npos; });
131
5
        return std::string(it, s.end());
132
5
    }
133
134
    std::string rtrim(const std::string &s, const std::string &charsToTrim)
135
10
    {
136
10
        auto it = std::find_if(s.rbegin(), s.rend(), [charsToTrim](char c)
137
29
                               { return charsToTrim.find(c) == std::string::npos; });
138
10
        return std::string(s.begin(), it.base());
139
10
    }
140
141
    std::string trim(const std::string &s, const std::string &charsToTrim)
142
5
    {
143
5
        return rtrim(ltrim(s, charsToTrim), charsToTrim);
144
5
    }
145
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/HDWallet/wallet.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "wallet.h"
2
#include "Utils/Utils.h"
3
4
namespace Aptos::HDWallet
5
{
6
    const std::string Wallet::DerivationPath = "m/44'/637'/x'/0'/0'";
7
    Account Wallet::account() const
8
2
    {
9
2
        return _account;
10
2
    }
11
12
    libbitcoin::data_chunk Wallet::DeriveMnemonicSeed()
13
4
    {
14
4
        auto hd_seed = bc::wallet::decode_mnemonic(wordList);
15
4
        return bc::to_chunk(hd_seed);
16
4
    }
17
18
    void Wallet::InitializeFirstAccount()
19
3
    {
20
3
        _ed25519Bip32 = std::make_unique<Ed25519Bip32>(_seed);
21
3
        _account = GetDerivedAccount(0);
22
3
    }
23
24
    Account Wallet::GetDerivedAccount(int index)
25
3
    {
26
3
        if (_seedMode != SeedMode::Ed25519Bip32)
27
0
        {
28
0
            throw std::runtime_error("Seed mode cannot derive Ed25519 based BIP32 keys");
29
0
        }
30
31
3
        std::string path = DerivationPath;
32
3
        size_t found = path.find("x");
33
3
        if (found != std::string::npos)
34
3
        {
35
3
            path.replace(found, 1, std::to_string(index));
36
3
        }
37
3
        std::pair<CryptoPP::SecByteBlock, CryptoPP::SecByteBlock> account = _ed25519Bip32->DerivePath(path);
38
3
        std::pair<CryptoPP::SecByteBlock, CryptoPP::SecByteBlock> keyPair = Utils::EdKeyPairFromSeed(account.first);
39
40
3
        return Account(keyPair.first, keyPair.second);
41
3
    }
42
43
    void Wallet::InitializeSeed()
44
3
    {
45
3
        _seed = DeriveMnemonicSeed();
46
3
        InitializeFirstAccount();
47
3
    }
48
49
    Wallet::Wallet(const std::string &mnemonicWords, SeedMode seedMode)
50
        : _seedMode(seedMode)
51
3
    {
52
3
        wordList = bc::split(mnemonicWords, " ", true);
53
        //    wordList = bc::wallet::create_mnemonic(my_word_list, bc::wallet::language::en);
54
3
        InitializeSeed();
55
3
    }
56
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Test/test_account.cpp
Line
Count
Source
1
//
2
// Created by Anh NPH on 27/09/2023.
3
//
4
5
#include "gtest/gtest.h"
6
#include <string>
7
#define private public
8
#include "../Accounts/Signature.h"
9
#include "../Accounts/PublicKey.h"
10
#include "../Accounts/PrivateKey.h"
11
#include "../Accounts/AccountAddress.h"
12
#include "../BCS/Serialization.h"
13
#include "../Accounts/multipublickey.h"
14
#include "../HDWallet/Utils/Utils.h"
15
#include "../Accounts/multisignature.h"
16
#include "../Accounts/Account.h"
17
#include "../Accounts/AuthenticationKey.h"
18
#include "../Accounts/Types/MultiEd25519PublicKey.h"
19
#include "../Accounts/Ed25519Bip32.h"
20
21
using namespace Aptos::Accounts;
22
using namespace Aptos;
23
// Extended PrivateKey for reference
24
CryptoPP::SecByteBlock g_extendedPrivateKeyBytes = Utils::ByteVectorToSecBlock({
25
    100, 245, 118, 3, 181, 138, 241, 105,
26
    7, 193, 138, 134, 97, 35, 40, 110,
27
    28, 188, 232, 151, 144, 97, 53, 88,
28
    220, 23, 117, 171, 179, 252, 92, 140,
29
    88, 110, 60, 141, 68, 125, 118, 121,
30
    34, 46, 19, 144, 51, 227, 130, 2,
31
    53, 227, 61, 165, 9, 30, 155, 11,
32
    184, 241, 161, 18, 207, 12, 143, 245
33
});
34
CryptoPP::SecByteBlock g_privateKeyBytes = Utils::ByteVectorToSecBlock({
35
    100, 245, 118, 3, 181, 138, 241, 105,
36
    7, 193, 138, 134, 97, 35, 40, 110,
37
    28, 188, 232, 151, 144, 97, 53, 88,
38
    220, 23, 117, 171, 179, 252, 92, 140
39
});
40
41
std::string g_privateKeyHex = "0x64f57603b58af16907c18a866123286e1cbce89790613558dc1775abb3fc5c8c";
42
43
CryptoPP::SecByteBlock g_privateKeySerializedOutput = Utils::ByteVectorToSecBlock({
44
    32, 100, 245, 118, 3, 181, 138, 241,
45
    105, 7, 193, 138, 134, 97, 35, 40,
46
    110, 28, 188, 232, 151, 144, 97, 53,
47
    88, 220, 23, 117, 171, 179, 252, 92, 140
48
});
49
50
CryptoPP::SecByteBlock g_publicKeyBytes = Utils::ByteVectorToSecBlock({
51
    88, 110, 60, 141, 68, 125, 118, 121,
52
    34, 46, 19, 144, 51, 227, 130, 2,
53
    53, 227, 61, 165, 9, 30, 155, 11,
54
    184, 241, 161, 18, 207, 12, 143, 245
55
});
56
std::string g_publicKeyHex = "0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5";
57
58
std::string g_accountAddress = "0x9f628c43d1c1c0f54683cf5ccbd2b944608df4ff2649841053b1790a4d7c187d";
59
60
CryptoPP::SecByteBlock g_publicKeySerializedOutput = Utils::ByteVectorToSecBlock({
61
    32, 88, 110, 60, 141, 68, 125, 118,
62
    121, 34, 46, 19, 144, 51, 227, 130,
63
    2, 53, 227, 61, 165, 9, 30, 155,
64
    11, 184, 241, 161, 18, 207, 12, 143, 245
65
});
66
67
CryptoPP::SecByteBlock g_privateKeyBytesInvalid = Utils::ByteVectorToSecBlock({
68
    100, 245, 118, 3, 181, 138, 241, 105,
69
    7, 193, 138, 134, 97, 35, 40, 110,
70
    28, 188, 232, 151, 144, 97, 53, 88,
71
    220, 23, 117, 171, 179, 252, 92, 140,
72
    88, 110, 60, 141, 68, 125, 118, 121,
73
    34, 46, 19, 144, 51, 227, 130, 2,
74
    53, 227, 61, 165, 9, 30, 155, 11,
75
});
76
77
CryptoPP::SecByteBlock g_publicKeyBytesInvalid = Utils::ByteVectorToSecBlock({
78
    88, 110, 60, 141, 68, 125, 118, 121,
79
    34, 46, 19, 144, 51, 227, 130, 2,
80
    53, 227, 61, 165, 9, 30, 155, 11,
81
    184, 241, 161, 18, 207, 12, 143, 245
82
});
83
84
std::string g_accountAddressHex = "0x9f628c43d1c1c0f54683cf5ccbd2b944608df4ff2649841053b1790a4d7c187d";
85
std::string g_ccountAuthKeyHex = "0x9f628c43d1c1c0f54683cf5ccbd2b944608df4ff2649841053b1790a4d7c187d";
86
87
CryptoPP::SecByteBlock g_messageUtf8Bytes = Utils::ByteVectorToSecBlock({
88
                                                                         87, 69, 76, 67, 79, 77, 69, 32,
89
                                                                         84, 79, 32, 65, 80, 84, 79, 83, 33 });
90
std::string g_message = "WELCOME TO APTOS!";
91
92
CryptoPP::SecByteBlock g_signatureBytes = Utils::ByteVectorToSecBlock({
93
    170, 66, 187, 194, 169, 252, 117, 27,
94
    238, 238, 59, 49, 43, 132, 82, 196,
95
    69, 199, 212, 171, 134, 152, 3, 107,
96
    12, 249, 242, 228, 106, 9, 139, 176,
97
    44, 54, 159, 188, 141, 254, 253, 35,
98
    26, 18, 141, 138, 75, 185, 173, 207,
99
    228, 94, 7, 24, 139, 117, 140, 58,
100
    211, 152, 215, 248, 78, 130, 239, 5
101
});
102
103
Signature signatureObject(g_signatureBytes);
104
105
std::string g_signatureHex = "0xaa42bbc2a9fc751beeee3b312b8452c445c7d4ab8698036b0cf9f2e46a098bb02c369fbc8dfefd231a128d8a4bb9adcfe45e07188b758c3ad398d7f84e82ef05";
106
107
CryptoPP::SecByteBlock g_signatureSerializedOutput = Utils::ByteVectorToSecBlock({
108
                                                                                  64, 170, 66, 187, 194, 169, 252, 117,
109
                                                                                  27, 238, 238, 59, 49, 43, 132, 82,
110
                                                                                  196, 69, 199, 212, 171, 134, 152, 3,
111
                                                                                  107, 12, 249, 242, 228, 106, 9, 139,
112
                                                                                  176, 44, 54, 159, 188, 141, 254, 253,
113
                                                                                  35, 26, 18, 141, 138, 75, 185, 173,
114
                                                                                  207, 228, 94, 7, 24, 139, 117, 140,
115
                                                                                  58, 211, 152, 215, 248, 78, 130, 239, 5 });
116
117
1
TEST(AccountTest, GeneratePrivateKeysWithBytesSuccess) {
118
1
    PrivateKey* privateKey = new PrivateKey(g_privateKeyBytes);
119
1
    ASSERT_TRUE(privateKey->KeyBytes().data() != nullptr);
120
1
    ASSERT_EQ(32, privateKey->KeyBytes().size());
121
1
    ASSERT_EQ(privateKey->KeyBytes(), g_privateKeyBytes);
122
123
1
    std::string privateKeyHex = privateKey->Key();
124
1
    ASSERT_EQ(privateKeyHex, g_privateKeyHex);
125
1
}
126
127
TEST(AccountTest, GenerateKeysWithBytesSuccess)
128
1
{
129
1
    PrivateKey* privateKey = new PrivateKey(g_privateKeyBytes);
130
1
    PublicKey* publicKey = new PublicKey(g_publicKeyBytes);
131
132
1
    ASSERT_TRUE(privateKey->KeyBytes().data() != nullptr);
133
1
    ASSERT_TRUE(publicKey->KeyBytes().data() != nullptr);
134
135
1
    std::string privateKeyHex = privateKey->ToString();
136
1
    std::string publicKeyHex = publicKey->ToString();
137
138
1
    ASSERT_EQ(privateKeyHex, g_privateKeyHex);
139
1
    ASSERT_EQ(publicKeyHex, g_publicKeyHex);
140
1
}
141
142
TEST(AccountTest, GenerateKeysWithStringSuccess)
143
1
{
144
1
    PrivateKey* privateKey = new PrivateKey(g_privateKeyHex);
145
1
    PublicKey* publicKey = new PublicKey(g_publicKeyHex);
146
147
1
    ASSERT_TRUE(privateKey->KeyBytes().data() != nullptr);
148
1
    ASSERT_TRUE(publicKey->KeyBytes().data() != nullptr);
149
150
1
    ASSERT_EQ(privateKey->KeyBytes(), g_privateKeyBytes);
151
1
    ASSERT_EQ(publicKey->KeyBytes(), g_publicKeyBytes);
152
153
1
    std::string privateKeyHex = privateKey->Key();
154
1
    std::string publicKeyHex = publicKey->Key();
155
156
1
    ASSERT_EQ(privateKeyHex, g_privateKeyHex);
157
1
    ASSERT_EQ(publicKeyHex, g_publicKeyHex);
158
1
}
159
160
TEST(AccountTest, GeneratePublicKeyFromPrivateKeySuccess)
161
1
{
162
1
    PrivateKey* privateKey = new PrivateKey(g_privateKeyHex);
163
1
    PublicKey publicKey = privateKey->GetPublicKey();
164
165
1
    ASSERT_EQ(g_publicKeyBytes, publicKey.KeyBytes());
166
1
}
167
168
TEST(AccountTest, PrivateKeyFromHexSignSuccess)
169
1
{
170
1
    PrivateKey * privateKey = new PrivateKey(g_privateKeyHex);
171
1
    ASSERT_EQ(privateKey->Key(), g_privateKeyHex);
172
1
    ASSERT_EQ(privateKey->KeyBytes(), g_privateKeyBytes);
173
174
1
    Signature signature = privateKey->Sign(g_messageUtf8Bytes);
175
1
    ASSERT_EQ(signature, signatureObject);
176
1
}
177
178
TEST(AccountTest, PrivateKeyFromBytesSignSuccess)
179
1
{
180
1
    PrivateKey privateKey(g_privateKeyBytes);
181
1
    ASSERT_EQ(privateKey.Key(), g_privateKeyHex);
182
1
    ASSERT_EQ(privateKey.KeyBytes(), g_privateKeyBytes);
183
184
1
    Signature signature = privateKey.Sign(g_messageUtf8Bytes);
185
1
    ASSERT_EQ(signature, signatureObject);
186
1
}
187
188
TEST(AccountTest, InvalidKeyGeneration)
189
1
{
190
1
    ASSERT_THROW( {
191
1
        PrivateKey* privateKey = new PrivateKey(g_privateKeyBytesInvalid);
192
1
        PublicKey* publicKey = new PublicKey(g_publicKeyBytesInvalid);
193
1
    },std::invalid_argument);
194
1
}
195
196
TEST(AccountTest, PublicKeySerialization)
197
1
{
198
1
    Serialization serializer;
199
1
    PublicKey* publicKey = new PublicKey(g_publicKeyBytes);
200
1
    publicKey->Serialize(serializer);
201
1
    CryptoPP::SecByteBlock output = Utils::ByteVectorToSecBlock(serializer.GetBytes());
202
203
1
    ASSERT_EQ(output, g_publicKeySerializedOutput);
204
1
}
205
206
TEST(AccountTest, PublicKeyDeserialization)
207
1
{
208
1
    Serialization serializer;
209
1
    PublicKey publicKey(g_publicKeyBytes);
210
1
    publicKey.Serialize(serializer);
211
1
    CryptoPP::SecByteBlock output = Utils::ByteVectorToSecBlock(serializer.GetBytes());
212
213
1
    ASSERT_EQ(output, g_publicKeySerializedOutput);
214
215
1
    Deserialization deserializer(Utils::SecBlockToByteVector(output));
216
1
    auto actualDeserialized = std::dynamic_pointer_cast<PublicKey>(PublicKey::Deserialize(deserializer));
217
218
1
    ASSERT_EQ(publicKey, *actualDeserialized);
219
1
}
220
221
TEST(AccountTest, PrivateKeySerialization)
222
1
{
223
1
    Serialization serializer;
224
1
    PrivateKey privateKey(g_privateKeyBytes);
225
1
    privateKey.Serialize(serializer);
226
1
    CryptoPP::SecByteBlock output = Utils::ByteVectorToSecBlock(serializer.GetBytes());
227
228
1
    ASSERT_EQ(output, g_privateKeySerializedOutput);
229
1
}
230
231
TEST(AccountTest, SignatureEquality)
232
1
{
233
1
    Signature* sigOne = new Signature(g_signatureBytes);
234
1
    Signature* sigTwo = new Signature(g_signatureBytes);
235
1
    ASSERT_TRUE(sigOne->Equals(*sigTwo));
236
1
}
237
238
TEST(AccountTest, SignatureSerialization)
239
1
{
240
1
    Serialization serializer;
241
1
    Signature sig(g_signatureBytes);
242
1
    sig.Serialize(serializer);
243
1
    CryptoPP::SecByteBlock output = Utils::ByteVectorToSecBlock(serializer.GetBytes());
244
1
    ASSERT_EQ(output, g_signatureSerializedOutput);
245
1
}
246
247
TEST(AccountTest, SignatureDeserialization)
248
1
{
249
1
    Serialization serializer;
250
1
    Signature sig(g_signatureBytes);
251
1
    sig.Serialize(serializer);
252
1
    CryptoPP::SecByteBlock output = Utils::ByteVectorToSecBlock(serializer.GetBytes());
253
254
1
    Deserialization deser(Utils::SecBlockToByteVector(output));
255
1
    auto actualSig = std::dynamic_pointer_cast<Signature>(Signature::Deserialize(deser));
256
1
    ASSERT_EQ(sig, *actualSig);
257
1
}
258
259
1
TEST(AccountTests, GenerateAccountAddressFromPublicKey) {
260
1
    PublicKey publicKey(g_publicKeyBytes);
261
1
    AccountAddress accountAddress = AccountAddress::FromKey(publicKey.KeyBytes());
262
1
    ASSERT_EQ(accountAddress.ToString(), g_accountAddressHex);
263
1
}
264
265
266
1
TEST(AccountTests, CreateAccountFromKeys) {
267
1
    Account acc(g_privateKeyBytes, g_publicKeyBytes);
268
1
    auto privateKey = acc.getPrivateKey();
269
1
    auto publicKey = acc.getPublicKey();
270
271
1
    PublicKey validPublicKey(g_publicKeyBytes);
272
1
    PrivateKey validPrivateKey(g_privateKeyBytes);
273
274
1
    ASSERT_TRUE(privateKey->Key() == validPrivateKey.Key());
275
1
    ASSERT_TRUE(publicKey->Key() == validPublicKey.Key());
276
1
}
277
278
1
TEST(AccountTests, GenerateAccountFromPrivateKeyStringSuccess) {
279
1
    Account acc = Account::LoadKey(g_privateKeyHex);
280
1
    auto privateKey = acc.getPrivateKey();
281
1
    auto publicKey = acc.getPublicKey();
282
283
1
    PublicKey expectedPublicKey(g_publicKeyBytes);
284
1
    PrivateKey expectedPrivateKey(g_privateKeyBytes);
285
286
1
    ASSERT_TRUE(privateKey->Key() == expectedPrivateKey.Key());
287
1
    ASSERT_TRUE(publicKey->Key() == expectedPublicKey.Key());
288
289
1
    ASSERT_EQ(g_accountAddress, acc.getAccountAddress()->ToString());
290
1
}
291
1
TEST(AccountTests, CreateDefaultAccountSuccess) {
292
1
    Account acc = Account();
293
1
    ASSERT_TRUE(acc.getPrivateKey() != nullptr);
294
1
    ASSERT_TRUE(acc.getPublicKey() != nullptr);
295
1
    ASSERT_TRUE(acc.getAccountAddress() != nullptr);
296
1
}
297
298
1
TEST(AccountTests, InvalidAccountCreationWithShorterKeys) {
299
1
    ASSERT_THROW(Account acc(g_privateKeyBytesInvalid, g_publicKeyBytesInvalid), std::invalid_argument);
300
1
}
301
302
1
TEST(AccountTests, AuthKeyGeneration) {
303
1
    Account acc = Account(g_privateKeyBytes, g_publicKeyBytes);
304
1
    std::string authKey = acc.AuthKey();
305
1
    ASSERT_EQ(authKey, g_ccountAuthKeyHex);
306
1
}
307
308
1
TEST(AccountTests, AccountSignSuccess) {
309
1
    Account acc = Account(g_privateKeyBytes, g_publicKeyBytes);
310
1
    Signature signature = acc.Sign(g_messageUtf8Bytes);
311
1
    ASSERT_EQ(signature, signatureObject);
312
1
}
313
314
1
TEST(AccountTests, AccountSignVerify) {
315
1
    Account acc = Account(g_privateKeyBytes, g_publicKeyBytes);
316
1
    Signature signature = acc.Sign(g_messageUtf8Bytes);
317
1
    ASSERT_EQ(signature, signatureObject);
318
1
    bool verify = acc.Verify(g_messageUtf8Bytes, signature);
319
1
    ASSERT_TRUE(verify);
320
1
}
321
322
323
1
TEST(AccountTests, TestMultisig) {
324
    //Generate signatory private keys.
325
1
    PrivateKey privateKey1 = PrivateKey::FromHex(
326
1
        "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe"
327
1
        );
328
1
    PrivateKey privateKey2 = PrivateKey::FromHex(
329
1
        "1e70e49b78f976644e2c51754a2f049d3ff041869c669523ba95b172c7329901"
330
1
        );
331
332
    // Generate multisig public key with threshold of 1.
333
1
    std::vector<PublicKey> publicKeys;
334
1
    publicKeys.push_back(privateKey1.GetPublicKey());
335
1
    publicKeys.push_back(privateKey2.GetPublicKey());
336
1
    MultiPublicKey multiSigPublicKey = MultiPublicKey(publicKeys, 1);
337
338
    // Get public key BCS representation.
339
1
    Serialization serializer;
340
1
    multiSigPublicKey.Serialize(serializer);
341
1
    std::string publicKeyBcs = Utils::HexStringFromByteArray(serializer.GetBytes());
342
    // Check against expected BCS representation.
343
1
    std::string expectedPublicKeyBcs = "41754bb6a4720a658bdd5f532995955db0971ad3519acbde2f1149c3857348006c" \
344
1
        "1634cd4607073f2be4a6f2aadc2b866ddb117398a675f2096ed906b20e0bf2c901";
345
346
1
    ASSERT_EQ(publicKeyBcs, expectedPublicKeyBcs);
347
348
    // Get public key bytes representation.
349
1
    std::vector<uint8_t> publicKeyBytes = multiSigPublicKey.ToBytes();
350
351
    // Convert back to multisig class instance from bytes.
352
1
    MultiPublicKey multisigPublicKey = MultiPublicKey::FromBytes(publicKeyBytes);
353
354
    // Get public key BCS representation.
355
1
    serializer = Serialization();
356
1
    multisigPublicKey.Serialize(serializer);
357
1
    std::string publicKeyBCs = Utils::HexStringFromByteArray(serializer.GetBytes());
358
359
    // Assert BCS representation is the same.
360
1
    ASSERT_EQ(publicKeyBcs, publicKeyBCs);
361
362
    // Have one signer sign arbitrary message.
363
1
    Signature signature = privateKey2.Sign(Utils::StringToSecByteBlock("multisig"));
364
365
    // Compose multisig signature.
366
1
    std::vector<std::pair<PublicKey, Signature>> signMap = {
367
1
        std::make_pair(privateKey2.GetPublicKey(), signature)
368
1
    };
369
1
    MultiSignature multiSignature = MultiSignature(multisigPublicKey, signMap);
370
371
    // Get signature BCS representation.
372
1
    serializer = Serialization();
373
1
    multiSignature.Serialize(serializer);
374
1
    std::vector<uint8_t> multisigBcsBytes = serializer.GetBytes();
375
1
    std::string multisigSignatureBcs = Utils::HexStringFromByteArray(serializer.GetBytes());
376
377
    // Check against expected BCS representation.
378
1
    std::string expectedMultisigSignatureBcs = "4402e90d8f300d79963cb7159ffa6f620f5bba4af5d32a7176bfb5480b43897cf4886bbb4042182f4647c9b04f02dbf989966f0facceec52d22bdcc7ce631bfc0c40000000";
379
380
1
    ASSERT_EQ(multisigSignatureBcs, expectedMultisigSignatureBcs);
381
1
}
382
383
384
1
TEST(AccountTests, TestMultiEd25519) {
385
1
    PrivateKey privateKey1 = PrivateKey::FromHex(
386
1
        "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe"
387
1
        );
388
389
1
    PrivateKey privateKey2 = PrivateKey::FromHex(
390
1
        "1e70e49b78f976644e2c51754a2f049d3ff041869c669523ba95b172c7329901"
391
1
        );
392
393
1
    MultiPublicKey multiSigPublicKey = MultiPublicKey(std::vector<PublicKey> {privateKey1.GetPublicKey(), privateKey2.GetPublicKey()}, 1);
394
395
1
    AccountAddress expected = AccountAddress::FromHex("835bb8c5ee481062946b18bbb3b42a40b998d6bf5316ca63834c959dc739acf0");
396
397
1
    AccountAddress actual = AccountAddress::FromMultiEd25519(multiSigPublicKey);
398
399
1
    ASSERT_EQ(expected, actual);
400
1
}
401
402
403
1
TEST(AccountTests, TestResourceAccount) {
404
1
    AccountAddress baseAddress = AccountAddress::FromHex("b0b");
405
1
    AccountAddress expected = AccountAddress::FromHex("ee89f8c763c27f9d942d496c1a0dcf32d5eacfe78416f9486b8db66155b163b0");
406
407
1
    std::vector<uint8_t> seed = {0x0b, 0x00, 0x0b};
408
1
    AccountAddress actual = AccountAddress::ForResourceAccount(baseAddress, Utils::ByteVectorToSecBlock(seed));
409
410
1
    ASSERT_EQ(actual, expected);
411
1
}
412
413
414
1
TEST(AccountTests, TestNamedObject) {
415
1
    AccountAddress baseAddress = AccountAddress::FromHex("b0b");
416
1
    AccountAddress expected = AccountAddress::FromHex("f417184602a828a3819edf5e36285ebef5e4db1ba36270be580d6fd2d7bcc321");
417
418
1
    CryptoPP::SecByteBlock seed = Utils::ByteVectorToSecBlock(
419
1
        {'b', 'o', 'b', '\'', 's', ' ', 'c', 'o', 'l', 'l', 'e', 'c', 't', 'i', 'o', 'n'});
420
1
    AccountAddress actual = AccountAddress::ForNamedObject(baseAddress, seed);
421
422
1
    ASSERT_EQ(actual, expected);
423
1
}
424
425
426
1
TEST(AccountTests, TestCollection) {
427
1
    AccountAddress baseAddress = AccountAddress::FromHex("b0b");
428
1
    AccountAddress expected = AccountAddress::FromHex("f417184602a828a3819edf5e36285ebef5e4db1ba36270be580d6fd2d7bcc321");
429
430
1
    AccountAddress actual = AccountAddress::ForNamedCollection(baseAddress, "bob's collection");
431
432
1
    ASSERT_EQ(actual, expected);
433
1
}
434
435
436
1
TEST(AccountTests, TestToken) {
437
1
    AccountAddress baseAddress = AccountAddress::FromHex("b0b");
438
1
    AccountAddress expected = AccountAddress::FromHex("e20d1f22a5400ba7be0f515b7cbd00edc42dbcc31acc01e31128b2b5ddb3c56e");
439
440
1
    AccountAddress actual = AccountAddress::ForNamedToken(baseAddress, "bob's collection", "bob's token");
441
442
1
    ASSERT_EQ(actual, expected);
443
1
}
444
445
446
447
1
TEST(AccountTests, TestToStandardString) {
448
    // Test special address: 0x0
449
1
    ASSERT_EQ(AccountAddress::FromHex("0x0000000000000000000000000000000000000000000000000000000000000000").ToString(), "0x0");
450
451
    // Test special address: 0x1
452
1
    ASSERT_EQ(AccountAddress::FromHex("0x0000000000000000000000000000000000000000000000000000000000000001").ToString(), "0x1");
453
454
    // Test special address: 0x4
455
1
    ASSERT_EQ(AccountAddress::FromHex("0x0000000000000000000000000000000000000000000000000000000000000004").ToString(), "0x4");
456
457
    // Test special address: 0xF
458
1
    ASSERT_EQ(AccountAddress::FromHex("0x000000000000000000000000000000000000000000000000000000000000000f").ToString(), "0xf");
459
460
    // Test special address from short no 0x: d
461
1
    ASSERT_EQ(AccountAddress::FromHex("d").ToString(), "0xd");
462
463
    // Test non-special address from long:
464
    // 0x0000000000000000000000000000000000000000000000000000000000000010
465
1
    ASSERT_EQ(AccountAddress::FromHex("0x0000000000000000000000000000000000000000000000000000000000000010").ToString(), "0x0000000000000000000000000000000000000000000000000000000000000010");
466
467
    // Test non-special address from long:
468
    // 0x000000000000000000000000000000000000000000000000000000000000001f
469
1
    ASSERT_EQ(AccountAddress::FromHex("0x000000000000000000000000000000000000000000000000000000000000001f").ToString(), "0x000000000000000000000000000000000000000000000000000000000000001f");
470
471
    // Test non-special address from long:
472
    // 0x00000000000000000000000000000000000000000000000000000000000000a0
473
1
    ASSERT_EQ(AccountAddress::FromHex("0x00000000000000000000000000000000000000000000000000000000000000a0").ToString(), "0x00000000000000000000000000000000000000000000000000000000000000a0");
474
475
    // Test non-special address from long no 0x:
476
    // ca843279e3427144cead5e4d5999a3d0ca843279e3427144cead5e4d5999a3d0
477
1
    ASSERT_EQ(AccountAddress::FromHex("ca843279e3427144cead5e4d5999a3d0ca843279e3427144cead5e4d5999a3d0").ToString(), "0xca843279e3427144cead5e4d5999a3d0ca843279e3427144cead5e4d5999a3d0");
478
479
    // Test non-special address from long no 0x:
480
    // 1000000000000000000000000000000000000000000000000000000000000000
481
1
    ASSERT_EQ(AccountAddress::FromHex("1000000000000000000000000000000000000000000000000000000000000000").ToString(), "0x1000000000000000000000000000000000000000000000000000000000000000");
482
483
    // Demonstrate that neither leading nor trailing zeroes get trimmed for
484
    // non-special addresses:
485
    // 0f00000000000000000000000000000000000000000000000000000000000000
486
1
    ASSERT_EQ(AccountAddress::FromHex("0f00000000000000000000000000000000000000000000000000000000000000").ToString(), "0x0f00000000000000000000000000000000000000000000000000000000000000");
487
1
}
488
489
TEST(AccountAddressTests, GetHashCodeConsistency)
490
1
{
491
    // Create two AccountAddress instances with the same value
492
1
    AccountAddress address1 = AccountAddress::FromHex("123abc");
493
1
    AccountAddress address2 = AccountAddress::FromHex("123abc");
494
495
    // Get hash codes
496
1
    size_t hash1 = address1.GetHashCode();
497
1
    size_t hash2 = address2.GetHashCode();
498
499
    // Test if the same address returns the same hash code
500
1
    ASSERT_EQ(hash1, hash2);
501
1
}
502
503
TEST(AccountAddressTests, VariantMethod)
504
1
{
505
    // Setup: Create an AccountAddress instance
506
1
    AccountAddress address = AccountAddress::FromHex("123abc"); // Example initialization
507
508
    // Execute: Call the Variant method
509
1
    TypeTag variantType = address.Variant();
510
511
    // Verify: Check if the returned TypeTag is ACCOUNT_ADDRESS
512
1
    ASSERT_EQ(variantType, TypeTag::ACCOUNT_ADDRESS);
513
1
}
514
515
TEST(AuthenticationKeyTest, ConstructorWithInvalidLength)
516
1
{
517
    // Setup: Create a SecByteBlock with the incorrect size
518
1
    size_t incorrectSize = AuthenticationKey::LENGTH + 1; // or any other incorrect size
519
1
    CryptoPP::SecByteBlock bytes(incorrectSize);
520
521
    // Execute & Verify: Ensure the constructor throws a std::invalid_argument exception
522
1
    ASSERT_THROW(AuthenticationKey authKey(bytes), std::invalid_argument);
523
1
}
524
525
TEST(AuthenticationKeyTest, FromMultiEd25519PublicKey)
526
1
{
527
    // Setup: Create a vector of PublicKeys and define a valid threshold
528
1
    PublicKey key1(g_publicKeyBytes);
529
1
    PublicKey key2(g_publicKeyHex);
530
1
    std::vector<PublicKey> publicKeys = {key1, key2};
531
1
    int validThreshold = 15;
532
533
    // Execute: Construct the MultiEd25519PublicKey
534
1
    Aptos::Accounts::Types::MultiEd25519PublicKey multiPublicKey(publicKeys, validThreshold);
535
536
1
    AuthenticationKey key = AuthenticationKey::FromMultiEd25519PublicKey(multiPublicKey);
537
538
1
    ASSERT_FALSE(key.DerivedAddress().empty());
539
1
}
540
   
541
542
TEST(PrivateKeyTest, ConstructorWithKeyInvalid)
543
1
{
544
    // Setup: Create a PrivateKey instance
545
1
    std::string keyString = "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5feaa";
546
    
547
1
    ASSERT_THROW(PrivateKey privateKey(keyString),std::invalid_argument);
548
1
}
549
550
TEST(PrivateKeyTest, ConstructorWithKeyEmpty)
551
1
{
552
    // Setup: Create a PrivateKey instance
553
1
    std::string keyString = "";
554
    
555
1
    ASSERT_THROW(PrivateKey privateKey(keyString),std::invalid_argument);
556
1
}
557
558
TEST(PrivateKeyTest, RandomMethod)
559
1
{
560
    // Setup: Create a PrivateKey instance
561
1
    std::string keyString = "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe";
562
1
    PrivateKey privateKey(keyString);
563
564
1
    PrivateKey randomPrivateKey = privateKey.Random();
565
    // Verify: Check if the serialized data matches the expected output
566
1
    ASSERT_TRUE(privateKey != randomPrivateKey);
567
1
}
568
569
TEST(PrivateKeyTest, SerializeMethodWithEmpty)
570
1
 {
571
     // Setup: Create a PrivateKey instance
572
1
     std::string keyString = "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe";
573
1
     PrivateKey privateKey(keyString);
574
 
575
1
    Serialization serializer;
576
577
    // Execute: Call the Serialize method
578
1
    privateKey.Serialize(serializer);
579
580
    // Retrieve the serialized data
581
1
    std::vector<uint8_t> serializedData = serializer.GetBytes();
582
583
    // Verify: Check if the serialized data matches the expected output
584
1
    ASSERT_TRUE(serializedData.size() > 0);
585
1
 }
586
587
588
TEST(PrivateKeyTest, EqualsWithDifferentKeys)
589
1
{
590
    // Setup: Create two PrivateKey instances with different keys
591
1
    PrivateKey key1 = PrivateKey::FromHex(
592
1
        "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe");
593
1
    PrivateKey key2 = PrivateKey::FromHex(
594
1
        "1e70e49b78f976644e2c51754a2f049d3ff041869c669523ba95b172c7329901");
595
596
    // Execute & Verify: Check if Equals returns false for different keys
597
1
    ASSERT_FALSE(key1 == key2);
598
1
}
599
600
TEST(PrivateKeyTest, SetKey)
601
1
{
602
    // Setup: Create a PrivateKey instance
603
1
    PrivateKey privateKey = PrivateKey::FromHex(
604
1
        "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe");
605
606
    // The key to set
607
1
    std::string testKey = "1e70e49b78f976644e2c51754a2f049d3ff041869c669523ba95b172c7329901";
608
609
    // Execute: Set the key
610
1
    privateKey.Key(testKey);
611
612
    // Verify: Check if the key was correctly set
613
    // This assumes there's a getter for the key. If not, this part needs to be adjusted.
614
1
    ASSERT_EQ(privateKey.Key(), testKey);
615
1
}
616
617
TEST(PrivateKeyTest, KeyBytesWithInvalidSize)
618
1
{
619
    // Setup: Create a PrivateKey instance and a SecByteBlock of incorrect size
620
1
    PrivateKey privateKey = PrivateKey::FromHex(
621
1
        "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe");
622
1
    size_t incorrectSize = PrivateKey::KeyLength + 1; // Assuming incorrect size
623
1
    CryptoPP::SecByteBlock invalidSizeBlock(incorrectSize);
624
625
    // Execute & Verify: Check if setting a SecByteBlock of incorrect size throws std::invalid_argument
626
1
    ASSERT_THROW(privateKey.KeyBytes(invalidSizeBlock), std::invalid_argument);
627
1
}
628
629
TEST(PrivateKeyTest, KeyBytesWithValidValue)
630
1
{
631
    // Setup: Create a PrivateKey instance and a valid SecByteBlock
632
1
    PrivateKey privateKey = PrivateKey::FromHex(
633
1
        "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe");
634
1
    CryptoPP::SecByteBlock validBlock(PrivateKey::KeyLength);
635
    // Optionally fill validBlock with some data
636
637
    // Execute: Set the valid SecByteBlock
638
1
    ASSERT_NO_THROW(privateKey.KeyBytes(validBlock));
639
640
    // Verify: Check if _keyBytes was set correctly
641
    // This assumes you have a way to get _keyBytes for verification
642
1
    ASSERT_EQ(privateKey.KeyBytes(), validBlock);
643
1
}
644
645
TEST(PrivateKeyTest, GetHashCode)
646
1
{
647
    // Setup: Create a PrivateKey instance and a valid SecByteBlock
648
1
    PrivateKey privateKey = PrivateKey::FromHex(
649
1
        "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe");
650
1
    CryptoPP::SecByteBlock validBlock(PrivateKey::KeyLength);
651
    // Optionally fill validBlock with some data
652
653
    // Execute: Set the valid SecByteBlock
654
1
    ASSERT_NO_THROW(privateKey.KeyBytes(validBlock));
655
656
1
    ASSERT_TRUE(privateKey.GetHashCode() != 0);
657
1
}
658
659
TEST(PrivateKeyTest, SignEmptyMessage)
660
1
{
661
    // Setup: Create a PrivateKey instance and a valid SecByteBlock
662
1
    PrivateKey privateKey = PrivateKey::FromHex(
663
1
        "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe");
664
1
    CryptoPP::SecByteBlock validBlock(PrivateKey::KeyLength);
665
    // Optionally fill validBlock with some data
666
1
    ASSERT_NO_THROW(privateKey.Sign(Utils::StringToSecByteBlock("multisig")));
667
1
}
668
669
670
671
TEST(PublicKeyTest, IsOnCurveAlwaysReturnsFalse)
672
1
{
673
    // Setup: Create a PublicKey instance with any key, since the method isn't implemented yet
674
    // Replace with an arbitrary key; it doesn't matter for this version of the test
675
1
    std::string arbitraryKey = "0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5";
676
1
    PublicKey publicKey(arbitraryKey);
677
678
    // Execute & Verify: Check if IsOnCurve currently always returns false
679
1
    ASSERT_FALSE(publicKey.IsOnCurve());
680
1
}
681
682
TEST(PublicKeyTest, GetHashCodeConsistency)
683
1
{
684
    // Setup: Create a PublicKey instance
685
1
    std::string keyString = "0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5";
686
1
    PublicKey publicKey(keyString);
687
688
    // Execute: Get the hash code twice
689
1
    size_t hashCode1 = publicKey.GetHashCode();
690
1
    size_t hashCode2 = publicKey.GetHashCode();
691
692
    // Verify: Check if the hash codes are consistent
693
1
    ASSERT_EQ(hashCode1, hashCode2);
694
1
}
695
696
TEST(PublicKeyTest, GetHashCodeDifferentKeys)
697
1
{
698
    // Setup: Create two PublicKey instances with different keys
699
1
    PublicKey key1("0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5");
700
1
    PublicKey key2("0x9f628c43d1c1c0f54683cf5ccbd2b944608df4ff2649841053b1790a4d7c187d");
701
702
    // Execute: Get the hash codes for each key
703
1
    size_t hashCode1 = key1.GetHashCode();
704
1
    size_t hashCode2 = key2.GetHashCode();
705
706
    // Verify: Ideally, the hash codes should be different
707
    // Note: This is not a strict requirement as hash collisions can happen
708
1
    ASSERT_NE(hashCode1, hashCode2);
709
1
}
710
711
TEST(PublicKeyTest, NotEqualsOperatorWithIdenticalKeys)
712
1
{
713
    // Setup: Create two PublicKey instances with the same key
714
1
    PublicKey key1("0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5");
715
1
    PublicKey key2("0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5");
716
717
    // Execute & Verify: Check if != operator returns false for identical keys
718
1
    ASSERT_FALSE(key1 != key2);
719
1
}
720
721
TEST(PublicKeyTest, NotEqualsOperatorWithDifferentKeys)
722
1
{
723
    // Setup: Create two PublicKey instances with different keys
724
1
    PublicKey key1("0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5");
725
1
    PublicKey key2("0x9f628c43d1c1c0f54683cf5ccbd2b944608df4ff2649841053b1790a4d7c187d");
726
727
    // Execute & Verify: Check if != operator returns true for different keys
728
1
    ASSERT_TRUE(key1 != key2);
729
1
}
730
731
TEST(PublicKeyTest, ConstructorWithEmptyValue)
732
1
{
733
    // Setup: Create an empty SecByteBlock
734
1
    CryptoPP::SecByteBlock emptySecByteBlock;
735
736
    // Execute & Verify: Check if constructing with an empty SecByteBlock throws std::invalid_argument
737
1
    ASSERT_THROW({
738
1
        PublicKey *publicKey = new PublicKey(emptySecByteBlock);
739
1
    },
740
1
                 std::invalid_argument);
741
1
}
742
743
TEST(PublicKeyTest, ConstructorWithInvalidKey)
744
1
{
745
    // Example of an invalid key string (e.g., too short)
746
1
    std::string invalidKey = "short_key";
747
748
    // Execute & Verify: Check if constructing with an invalid key string throws std::invalid_argument
749
1
    ASSERT_THROW({
750
1
        PublicKey *publicKey = new PublicKey(g_publicKeySerializedOutput);
751
1
    },
752
1
                 std::invalid_argument);
753
1
}
754
755
TEST(PublicKeyTest, ConstructorWithValidKey)
756
1
{
757
    // Example of a valid key string
758
1
    std::string validKey = "0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5"; // Replace with an actual valid key
759
760
    // Execute & Verify: Check if constructing with a valid key does not throw
761
1
    ASSERT_NO_THROW(PublicKey *publicKey = new PublicKey(g_publicKeyHex));
762
763
    // Additional verification steps can be added here if needed
764
1
}
765
766
TEST(PublicKeyTest, ConstructorWithEmptyKey)
767
1
{
768
    // Setup: Define an empty key
769
1
    std::string emptyKey;
770
771
    // Execute & Verify: Ensure the constructor throws an std::invalid_argument exception
772
    // when an empty key is passed
773
1
    ASSERT_THROW({
774
1
        PublicKey *publicKey = new PublicKey(emptyKey);
775
1
    },
776
1
                 std::invalid_argument);
777
1
}
778
779
// setKey PublicKey
780
TEST(PublicKeyTest, SetKeyWithEmptyString)
781
1
{
782
    // Setup: Create a PublicKey instance and an empty key string
783
1
    PublicKey publicKey(g_publicKeyHex);
784
1
    std::string emptyKey = "";
785
786
    // Execute & Verify: Ensure the method throws an std::invalid_argument exception
787
1
    ASSERT_THROW(publicKey.setKey(emptyKey), std::invalid_argument);
788
1
}
789
790
TEST(PublicKeyTest, SetKeyWithInvalidFormat)
791
1
{
792
    // Setup: Create a PublicKey instance and an invalid key string
793
1
    PublicKey publicKey(g_publicKeyHex);
794
1
    std::string invalidKey = "0x586e3c8d447d7679222e1aa39033e3820235e33da5091e9b0bb8f1a112cf0c8ff5";
795
796
    // Execute & Verify: Ensure the method throws an std::invalid_argument exception
797
1
    ASSERT_THROW(publicKey.setKey(invalidKey), std::invalid_argument);
798
1
}
799
800
TEST(PublicKeyTest, SetKeySuccessfully)
801
1
{
802
    // Setup: Create a PublicKey instance and a valid key string
803
1
    PublicKey publicKey(g_publicKeyHex);
804
1
    std::string validKey = "0x586e3c8d447d7679222e139033e3820235e33da5091e9b0bb8f1a112cf0c8ff5"; // Replace with a valid hex key format
805
806
    // Execute: Set the key
807
1
    ASSERT_NO_THROW(publicKey.setKey(validKey));
808
809
    // Verify: Check if the key was set correctly
810
    // This part of the test depends on the available public methods of PublicKey.
811
    // For example, if there's a method to get a property that changes when the key is set:
812
    // ASSERT_EQ(publicKey.getSomeProperty(), expectedPropertyValue);
813
1
}
814
815
// setKeyBytes PublicKey.cpp
816
TEST(PublicKeyTest, SetKeyBytesWithEmptyBlock)
817
1
{
818
    // Setup: Create a PublicKey instance and an empty SecByteBlock
819
1
    PublicKey publicKey(g_publicKeyBytes);
820
1
    CryptoPP::SecByteBlock emptyBlock;
821
822
    // Execute & Verify: Ensure the method throws an std::invalid_argument exception
823
1
    ASSERT_THROW(publicKey.setKeyBytes(emptyBlock), std::invalid_argument);
824
1
}
825
826
TEST(PublicKeyTest, SetKeyBytesWithIncorrectLength)
827
1
{
828
    // Setup: Create a PublicKey instance and a SecByteBlock of incorrect length
829
1
    PublicKey publicKey(g_publicKeyBytes);
830
1
    size_t incorrectLength = PublicKey::KeyLength - 1; // Assuming KeyLength is accessible
831
1
    CryptoPP::SecByteBlock blockWithIncorrectLength(incorrectLength);
832
833
    // Execute & Verify: Ensure the method throws an std::invalid_argument exception
834
1
    ASSERT_THROW(publicKey.setKeyBytes(blockWithIncorrectLength), std::invalid_argument);
835
1
}
836
837
TEST(PublicKeyTest, SetKeyBytesSuccessfully)
838
1
{
839
    // Setup: Create a PublicKey instance and a valid SecByteBlock
840
1
    PublicKey publicKey(g_publicKeyBytes);
841
1
    CryptoPP::SecByteBlock validBlock(PublicKey::KeyLength); // Assuming KeyLength is accessible
842
843
    // Execute: Set the key bytes
844
1
    ASSERT_NO_THROW(publicKey.setKeyBytes(validBlock));
845
846
    // Verify: Check if the key bytes were set correctly
847
    // This part of the test depends on the available public methods of PublicKey.
848
    // For example, if there's a method to get a property or the key bytes themselves:
849
    // ASSERT_EQ(publicKey.getSomeProperty(), expectedPropertyValue);
850
    // or
851
    // ASSERT_EQ(publicKey.getKeyBytes(), validBlock);
852
1
}
853
854
// MultiEd25519PublicKey MultiEd25519PublicKey.cpp
855
TEST(MultiEd25519PublicKeyTest, ConstructorThresholdExceedsLimit)
856
1
{
857
    // Setup: Create a vector of PublicKeys and define a threshold that exceeds the limit
858
1
    PublicKey key1(g_publicKeyBytes);
859
1
    PublicKey key2(g_publicKeyHex);
860
1
    std::vector<PublicKey> publicKeys = {key1, key2};
861
1
    int invalidThreshold = Aptos::Accounts::Types::MultiEd25519PublicKey::MAX_SIGNATURES_SUPPORTED + 1;
862
863
    // Execute & Verify: Ensure the constructor throws an std::invalid_argument exception
864
1
    ASSERT_THROW(Aptos::Accounts::Types::MultiEd25519PublicKey(publicKeys, invalidThreshold), std::invalid_argument);
865
1
}
866
867
TEST(MultiEd25519PublicKeyTest, ConstructorSuccessfulInitialization)
868
1
{
869
    // Setup: Create a vector of PublicKeys and define a valid threshold
870
1
    PublicKey key1(g_publicKeyBytes);
871
1
    PublicKey key2(g_publicKeyHex);
872
1
    std::vector<PublicKey> publicKeys = {key1, key2};
873
1
    int validThreshold = 15;
874
875
    // Execute: Construct the MultiEd25519PublicKey
876
1
    Aptos::Accounts::Types::MultiEd25519PublicKey multiPublicKey(publicKeys, validThreshold);
877
878
    // Verify: Check if the object is initialized correctly
879
    // This part of the test depends on the available public methods of MultiEd25519PublicKey.
880
    // For example:
881
1
    ASSERT_TRUE(multiPublicKey.PublicKeys.size() > 0);
882
1
}
883
884
TEST(Ed25519Bip32Test,IsValidPath)
885
1
{
886
1
    bool result = Ed25519Bip32::IsValidPath("");
887
1
    ASSERT_FALSE(result);
888
1
}
889
890
TEST(Ed25519Bip32Test,DerivePath)
891
1
{
892
1
    std::vector<uint8_t> seed;
893
1
    Ed25519Bip32 ed25519Bip32(seed);
894
1
    ASSERT_THROW(ed25519Bip32.DerivePath(""),std::invalid_argument);
895
1
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Test/test_serialization.cpp
Line
Count
Source (jump to first uncovered line)
1
// test_serialization.cpp
2
3
#include "gtest/gtest.h"
4
#include "../BCS/Serialization.h"
5
#include "../BCS/Deserialization.h"
6
#include "../BCS/BCSTypes.h"
7
#include "../BCS/BCSMap.h"
8
#include "../BCS/U32.h"
9
#include "../BCS/BString.h"
10
#include "../BCS//Sequence.h"
11
#include "../BCS/Bool.h"
12
#include <cryptopp/integer.h>
13
#include "../BCS/StructTag.h"
14
#include "../BCS/Bytes.h"
15
#include "../BCS/BCSMap.h"
16
#include "../BCS/U8.h"
17
#include "../BCS/U16.h"
18
#include "../BCS/U64.h"
19
#include "../BCS/U128.h"
20
#include "../BCS/U256.h"
21
#include <boost/endian/conversion.hpp>
22
#include "../HDWallet/Utils/Utils.h"
23
24
25
1
TEST(SerializationTest, BoolSerialize) {
26
1
    Serialization s;
27
1
    s.SerializeBool(true);
28
1
    std::vector<uint8_t> res = s.GetBytes();
29
30
1
    std::vector<uint8_t> expected = {1};
31
1
    ASSERT_EQ(expected, res);
32
1
}
33
34
1
TEST(SerializationTest, BoolTrueDeserialize) {
35
1
    bool actual = true;
36
1
    Serialization s;
37
1
    s.SerializeBool(actual);
38
1
    std::vector<uint8_t> res = s.GetBytes();
39
40
1
    Deserialization d(res);
41
1
    bool expected = d.DeserializeBool();
42
43
1
    ASSERT_EQ(expected, actual);
44
1
}
45
46
1
TEST(SerializationTest, BoolFalseSerialize) {
47
1
    Serialization s;
48
1
    s.SerializeBool(false);
49
1
    std::vector<uint8_t> res = s.GetBytes();
50
51
1
    std::vector<uint8_t> expected = {0};
52
1
    ASSERT_EQ(expected, res);
53
1
}
54
55
1
TEST(SerializationTest, BoolFalseDeserialize) {
56
1
    bool expected = false;
57
1
    Serialization s;
58
1
    s.SerializeBool(expected);
59
1
    std::vector<uint8_t> res = s.GetBytes();
60
61
1
    Deserialization d(res);
62
1
    bool actual = d.DeserializeBool();
63
64
1
    ASSERT_EQ(expected, actual);
65
1
}
66
67
1
TEST(SerializationTest, ByteArraySerialize) {
68
69
1
    std::string value = "1234567890";
70
71
1
    std::vector<uint8_t> bytes(value.begin(), value.end());
72
73
1
    Serialization s;
74
1
    s.SerializeBytes(bytes);
75
76
1
    std::vector<uint8_t> actual = s.GetBytes();
77
78
1
    std::vector<uint8_t> expected = {10, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
79
1
    ASSERT_EQ(expected, actual);
80
81
1
}
82
83
1
TEST(SerializationTest, ByteArrayDeserialize) {
84
1
    std::string value = "1234567890";
85
86
1
    std::vector<uint8_t> bytes(value.begin(), value.end());
87
88
1
    Serialization s;
89
1
    s.SerializeBytes(bytes);
90
1
    std::vector<uint8_t> expected = s.GetBytes();
91
92
1
    Deserialization d(expected);
93
1
    std::vector<uint8_t> actual = d.ToBytes();
94
95
1
    ASSERT_EQ(value.size(), actual.size());
96
1
    ASSERT_EQ(std::vector<uint8_t>(value.begin(), value.end()), actual);
97
1
}
98
99
1
TEST(SerializationTest, U8Serialize) {
100
101
1
    Serialization s;
102
1
    s.SerializeU8(123);
103
104
1
    std::vector<uint8_t> expected = {123};
105
1
    auto actual = s.GetBytes();
106
107
1
    ASSERT_EQ(expected, actual);
108
109
1
}
110
111
1
TEST(SerializationTest, U8Deserialize) {
112
113
1
    uint8_t expected = 123;
114
115
1
    Serialization s;
116
1
    s.SerializeU8(expected);
117
118
1
    std::vector<uint8_t> bytes = s.GetBytes();
119
120
1
    Deserialization d(bytes);
121
1
    uint8_t actual = d.DeserializeU8();
122
123
1
    ASSERT_EQ(expected, actual);
124
125
1
}
126
127
1
TEST(SerializationTest, U32Serialize) {
128
129
1
    uint32_t input = 57615782;
130
131
1
    Serialization s;
132
1
    s.SerializeU32(input);
133
134
1
    std::vector<uint8_t> expected = {166, 37, 111, 3};
135
1
    auto actual = s.GetBytes();
136
137
1
    ASSERT_EQ(expected, actual);
138
139
1
}
140
141
1
TEST(SerializationTest, U32Deserialize) {
142
143
1
    uint32_t expected = 57615782;
144
145
1
    Serialization s;
146
1
    s.SerializeU32(expected);
147
148
1
    std::vector<uint8_t> bytes = s.GetBytes();
149
150
1
    Deserialization d(bytes);
151
1
    uint32_t actual = d.DeserializeU32();
152
153
1
    ASSERT_EQ(expected, actual);
154
155
1
}
156
157
158
1
TEST(SerializationTest, U64Serialize) {
159
160
1
    uint64_t input = 9432012321182;
161
162
1
    Serialization s;
163
1
    s.SerializeU64(input);
164
165
1
    std::vector<uint8_t> expected = {158, 113, 190, 15, 148, 8, 0, 0};
166
1
    auto actual = s.GetBytes();
167
168
1
    ASSERT_EQ(expected, actual);
169
170
1
}
171
172
1
TEST(SerializationTest, U64Deserialize) {
173
174
1
    uint64_t expected = 9432012321182;
175
176
1
    Serialization s;
177
1
    s.SerializeU64(expected);
178
179
1
    std::vector<uint8_t> bytes = s.GetBytes();
180
181
1
    Deserialization d(bytes);
182
1
    uint64_t actual = d.DeserializeU64();
183
184
1
    ASSERT_EQ(expected, actual);
185
186
1
}
187
188
1
TEST(SerializationTest, U128Serialize) {
189
190
1
    CryptoPP::Integer input1 = 10;
191
192
1
    Serialization s1;
193
1
    s1.SerializeU128(input1);
194
195
1
    std::vector<uint8_t> expected1 = {10, 0, 0, 0, 0, 0, 0, 0,
196
1
                                      0, 0, 0, 0, 0, 0, 0, 0};
197
198
1
    ASSERT_EQ(expected1, s1.GetBytes());
199
200
201
1
    CryptoPP::Integer input2 = CryptoPP::Integer("749382032131231323910498053");
202
203
1
    Serialization s2;
204
1
    s2.SerializeU128(input2);
205
206
1
    std::vector<uint8_t> expected2 = {5, 231, 86, 201, 40, 241, 231, 92,
207
1
                                      209, 223, 107, 2, 0, 0, 0, 0};
208
209
1
    ASSERT_EQ(expected2, s2.GetBytes());
210
211
1
}
212
213
1
TEST(SerializationTest, U128Deserialize) {
214
1
    CryptoPP::Integer expected = 10;
215
1
    std::vector<uint8_t> bytes = Serialization().SerializeU128(expected).GetBytes();
216
1
    CryptoPP::Integer actual = Deserialization(bytes).DeserializeU128();
217
1
    ASSERT_EQ(expected, actual);
218
219
1
    expected = CryptoPP::Integer("749382032131231323910498053");
220
1
    bytes = Serialization().SerializeU128(expected).GetBytes();
221
1
    actual = Deserialization(bytes).DeserializeU128();
222
1
    ASSERT_EQ(expected, actual);
223
1
}
224
225
1
TEST(SerializationTest, U32AsUleb128Serialize) {
226
1
    std::vector<uint8_t> res = Serialization().SerializeU32AsUleb128(1160).GetBytes();
227
1
    std::vector<uint8_t> expected = {136, 9};
228
1
    ASSERT_EQ(expected, res);
229
1
}
230
231
1
TEST(SerializationTest, U32AsUleb128Deserialize) {
232
1
    uint32_t expected = 1160;
233
1
    std::vector<uint8_t> bytes = Serialization().SerializeU32AsUleb128(expected).GetBytes();
234
1
    uint32_t actual = Deserialization(bytes).DeserializeUleb128();
235
1
    ASSERT_EQ(expected, actual);
236
1
}
237
238
1
TEST(SerializationTest, StringSerialize) {
239
1
    std::vector<uint8_t> res = Serialization().SerializeString("potato UTF8: 🥔").GetBytes();
240
1
    std::vector<uint8_t> exp = { 17, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165, 148 };
241
1
    ASSERT_EQ(exp, res);
242
1
}
243
244
1
TEST(SerializationTest, StringDeserialize) {
245
1
    std::string expected = "potato UTF8: 🥔";
246
1
    std::vector<uint8_t> bytes = Serialization().SerializeString(expected).GetBytes();
247
1
    std::string actual = Deserialization(bytes).DeserializeString();
248
1
    ASSERT_EQ(expected, actual);
249
1
}
250
251
1
TEST(SerializationTest, StringLongSerialize) {
252
1
    std::string longString = "potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔";
253
1
    std::vector<uint8_t> res = Serialization().SerializeString(longString).GetBytes();
254
255
1
    std::vector<uint8_t> exp = { 231, 2, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
256
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
257
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
258
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
259
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
260
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
261
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
262
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
263
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
264
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
265
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
266
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
267
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
268
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
269
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
270
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
271
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
272
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
273
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
274
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
275
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
276
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
277
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
278
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
279
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
280
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
281
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
282
1
                                 148, 32, 112, 111, 116, 97, 116, 111, 32, 85, 84, 70,
283
1
                                 56, 58, 32, 240, 159, 165, 148, 32, 112, 111, 116, 97,
284
1
                                 116, 111, 32, 85, 84, 70, 56, 58, 32, 240, 159, 165,
285
1
                                 148 };
286
287
362
    for (int i =0; i < exp.size(); i++){
288
361
        ASSERT_EQ(exp[i], res[i]);
289
361
    }
290
1
}
291
292
1
TEST(SerializationTest, StringLongDeserialize) {
293
1
    std::string expected = "potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔 potato UTF8: 🥔";
294
1
    std::vector<uint8_t> bytes = Serialization().SerializeString(expected).GetBytes();
295
1
    std::string actual = Deserialization(bytes).DeserializeString();
296
297
1
    ASSERT_EQ(expected, actual);
298
1
}
299
300
using MapType = std::map<BString, std::shared_ptr<ISerializable>>;
301
302
1
TEST(SerializationTest, MapBStringU32Test) {
303
1
    MapType map;
304
1
    map[BString("a")] = std::make_shared<U32>(12345);
305
1
    map[BString("b")] = std::make_shared<U32>(99234);
306
1
    map[BString("c")] = std::make_shared<U32>(23829);
307
308
1
    BCSMap bcsMap(map);
309
1
    Serialization ser;
310
1
    bcsMap.Serialize(ser);
311
312
1
    std::vector<uint8_t> serialized = ser.GetBytes();
313
1
    std::vector<uint8_t> expected = {3, 1, 97, 57, 48, 0, 0, 1, 98, 162, 131, 1, 0, 1, 99, 21, 93, 0, 0};
314
315
1
    EXPECT_EQ(expected, serialized);
316
1
}
317
318
1
TEST(SerializationTest, Map_BString_U32_Deserialize) {
319
1
    MapType expectedMap;
320
1
    expectedMap[BString("x")] = std::make_shared<U32>(12345);
321
1
    expectedMap[BString("b")] = std::make_shared<U32>(99234);
322
1
    expectedMap[BString("c")] = std::make_shared<U32>(23829);
323
324
1
    BCSMap expectedBcsMap(expectedMap);
325
1
    Serialization ser;
326
1
    expectedBcsMap.Serialize(ser);
327
328
1
    std::vector<uint8_t> bytes = ser.GetBytes();
329
1
    Deserialization deser(bytes);
330
1
    BCSMap actualBcsMap = deser.DeserializeMap(
331
3
        [](Deserialization& d) -> std::shared_ptr<ISerializable> { return U32::Deserialize(d); });
332
333
1
    auto values = actualBcsMap.getValues();
334
    // Expect the keys and values to be the same, but in sorted order
335
1
    std::vector<BString> key;
336
1
    std::vector<std::shared_ptr<ISerializable>> value;
337
4
    for(auto it = values.begin(); it != values.end(); ++it) {
338
3
        key.push_back(it->first);
339
3
        value.push_back(it->second);
340
3
    }
341
342
1
    EXPECT_TRUE(BString("b").Equals(key[0]));
343
1
    EXPECT_TRUE(BString("c").Equals(key[1]));
344
1
    EXPECT_TRUE(BString("x").Equals(key[2]));
345
1
    EXPECT_TRUE(U32(99234).Equals(*(std::dynamic_pointer_cast<U32>(value[0]))));
346
1
    EXPECT_TRUE(U32(23829).Equals(*(std::dynamic_pointer_cast<U32>(value[1]))));
347
1
    EXPECT_TRUE(U32(12345).Equals(*(std::dynamic_pointer_cast<U32>(value[2]))));
348
1
}
349
350
351
1
TEST(SerializationTest, MapBStringU32Test1) {
352
1
    MapType map;
353
1
    map[BString("x")] = std::make_shared<U32>(12345);
354
1
    map[BString("b")] = std::make_shared<U32>(99234);
355
1
    map[BString("c")] = std::make_shared<U32>(23829);
356
357
1
    BCSMap bcsMap(map);
358
1
    Serialization ser;
359
1
    bcsMap.Serialize(ser);
360
361
1
    std::vector<uint8_t> serialized = ser.GetBytes();
362
1
    std::vector<uint8_t> expected = {3, 1, 98, 162, 131, 1, 0, 1, 99, 21, 93, 0, 0, 1, 120, 57, 48, 0, 0};
363
364
1
    EXPECT_EQ(expected, serialized);
365
1
}
366
367
1
TEST(SerializationTest, MapBStringU32Test2) {
368
1
    MapType map;
369
1
    map[BString("b")] = std::make_shared<U32>(12345);
370
1
    map[BString("x")] = std::make_shared<U32>(99234);
371
1
    map[BString("c")] = std::make_shared<U32>(23829);
372
373
1
    BCSMap bcsMap(map);
374
1
    Serialization ser;
375
1
    bcsMap.Serialize(ser);
376
377
1
    std::vector<uint8_t> serialized = ser.GetBytes();
378
1
    std::vector<uint8_t> expected = {3, 1, 98, 57, 48, 0, 0, 1, 99, 21, 93, 0, 0, 1, 120, 162, 131, 1, 0 };
379
380
1
    EXPECT_EQ(expected, serialized);
381
1
}
382
383
384
1
TEST(SerializationTest, MapBStringU32Test3) {
385
1
    MapType map;
386
1
    map[BString("b")] = std::make_shared<U32>(99234);
387
1
    map[BString("x")] = std::make_shared<U32>(12345);
388
1
    map[BString("c")] = std::make_shared<U32>(23829);
389
390
1
    BCSMap bcsMap(map);
391
1
    Serialization ser;
392
1
    bcsMap.Serialize(ser);
393
394
1
    std::vector<uint8_t> serialized = ser.GetBytes();
395
1
    std::vector<uint8_t> expected = {3, 1, 98, 162, 131, 1, 0, 1, 99, 21, 93, 0, 0, 1, 120, 57, 48, 0, 0 };
396
397
1
    EXPECT_EQ(expected, serialized);
398
1
}
399
400
1
TEST(SerializationTest, MapBStringBStringTest) {
401
1
    MapType map;
402
1
    map[BString("a")] = std::make_shared<BString>("a");
403
1
    map[BString("b")] = std::make_shared<BString>("b");
404
1
    map[BString("c")] = std::make_shared<BString>("c");
405
406
1
    BCSMap bcsMap(map);
407
1
    Serialization ser;
408
1
    bcsMap.Serialize(ser);
409
410
1
    std::vector<uint8_t> serialized = ser.GetBytes();
411
1
    std::vector<uint8_t> expected = {3, 1, 97, 1, 97, 1, 98, 1, 98, 1, 99, 1, 99 };
412
413
1
    EXPECT_EQ(expected, serialized);
414
1
}
415
416
1
TEST(SerializationTest, StringBytesEmptySerialize) {
417
1
    std::vector<uint8_t> value(1160, 0); // empty byte string of size 1160
418
419
1
    Serialization serializer;
420
1
    serializer.SerializeBytes(value);
421
1
    std::vector<uint8_t> res = serializer.GetBytes();
422
423
    // 1160 for byte array + 2 for length
424
1
    std::vector<uint8_t> exp(1162, 0);
425
1
    exp[0] = 136;
426
1
    exp[1] = 9;
427
428
1
    EXPECT_EQ(exp, res);
429
1
}
430
431
1
TEST(SerializationTest, MultipleValues_Serialize) {
432
1
    Serialization serializer;
433
1
    serializer.Serialize(std::string("potato"));
434
1
    serializer.Serialize(static_cast<uint32_t>(123));
435
1
    serializer.Serialize(true);
436
1
    serializer.Serialize(static_cast<uint32_t>(456));
437
1
    std::vector<uint8_t> res = serializer.GetBytes();
438
1
    std::vector<uint8_t> exp = { 6, 112, 111, 116, 97, 116, 111, 123, 0, 0, 0, 1, 200, 1, 0, 0 };
439
1
    EXPECT_EQ(exp, res);
440
1
}
441
442
1
TEST(SerializationTest, SequenceBStringEmptySerialize) {
443
1
    Serialization ser;
444
1
    std::vector<std::shared_ptr<ISerializable>> strArr = { std::make_shared<BString>("") };
445
1
    Sequence seq(strArr);
446
447
1
    seq.Serialize(ser);
448
449
1
    std::vector<uint8_t> actual = ser.GetBytes();
450
1
    std::vector<uint8_t> expected = { 1, 1, 0 };
451
1
    EXPECT_EQ(expected, actual);
452
1
}
453
454
1
TEST(SerializationTest, SequenceBStringLongDeserialize) {
455
1
    Serialization ser;
456
1
    std::vector<std::shared_ptr<ISerializable>> expectedStrArr = { std::make_shared<BString>("a"), std::make_shared<BString>("abc"),
457
1
                                                              std::make_shared<BString>("def"), std::make_shared<BString>("ghi") };
458
1
    ser.Serialize(expectedStrArr);
459
460
1
    Sequence expectedSeq(expectedStrArr);
461
462
1
    std::vector<uint8_t> actual = ser.GetBytes();
463
1
    std::vector<uint8_t> exp = { 4, 1, 97, 3, 97, 98, 99, 3, 100, 101, 102, 3, 103, 104, 105 };
464
1
    EXPECT_EQ(exp, actual);
465
466
1
    Deserialization deser(actual);
467
1
    std::vector<std::shared_ptr<ISerializable>> actualSequenceArr = deser.DeserializeSequence(
468
4
        [](Deserialization& d) -> std::shared_ptr<ISerializable> { return BString::Deserialize(d); });
469
470
5
    for (int i = 0; i < expectedStrArr.size(); i++){
471
4
        EXPECT_EQ(expectedStrArr[i]->ToString(), actualSequenceArr[i]->ToString());
472
4
    }
473
1
}
474
475
476
1
TEST(SerializationTest, SequenceBStringSerialize) {
477
1
    Serialization ser;
478
1
    std::vector<std::shared_ptr<ISerializable>> expectedStrArr = { std::make_shared<BString>("a"), std::make_shared<BString>("abc"),
479
1
                                                   std::make_shared<BString>("def"), std::make_shared<BString>("ghi") };
480
1
    ser.Serialize(expectedStrArr);
481
482
1
    std::vector<uint8_t> actual = ser.GetBytes();
483
1
    std::vector<uint8_t> exp = { 4, 1, 97, 3, 97, 98, 99, 3, 100, 101, 102, 3, 103, 104, 105 };
484
1
    EXPECT_EQ(exp, actual);
485
1
}
486
487
1
TEST(SerializationTest, SequenceBoolSerialize) {
488
1
    Serialization ser;
489
1
    std::vector<std::shared_ptr<ISerializable>> expectedStrArr = { std::make_shared<Bool>(false), std::make_shared<Bool>(true),
490
1
                                                   std::make_shared<Bool>(false)};
491
1
    ser.Serialize(expectedStrArr);
492
493
1
    std::vector<uint8_t> actual = ser.GetBytes();
494
1
    std::vector<uint8_t> exp = { 3, 0, 1, 0 };
495
1
    EXPECT_EQ(exp, actual);
496
1
}
497
498
1
TEST(SerializationTest, SequenceBoolDeserializer) {
499
1
    Serialization ser;
500
1
    std::vector<std::shared_ptr<ISerializable>> expectedBoolArr = { std::make_shared<Bool>(false), std::make_shared<Bool>(true),
501
1
                                                   std::make_shared<Bool>(false)};
502
1
    ser.Serialize(expectedBoolArr);
503
504
1
    std::vector<uint8_t> expectedByteArr = { 3, 0, 1, 0 };
505
1
    std::vector<uint8_t> actualByteArr = ser.GetBytes();
506
1
    EXPECT_EQ(expectedByteArr, actualByteArr);
507
508
1
    Deserialization deser(expectedByteArr);
509
1
    std::vector<std::shared_ptr<ISerializable>> actualBoolArr = deser.DeserializeSequence(
510
3
            [](Deserialization& d) -> std::shared_ptr<ISerializable> { return Bool::Deserialize(d); });
511
1
    EXPECT_EQ(expectedBoolArr.size(), actualBoolArr.size());
512
4
    for (std::size_t i = 0; i < expectedBoolArr.size(); ++i) {
513
3
        EXPECT_EQ(*std::dynamic_pointer_cast<Bool>(expectedBoolArr[i]),
514
3
                  *std::dynamic_pointer_cast<Bool>(actualBoolArr[i]));
515
3
    }
516
1
}
517
518
519
//Addition testcase for Unit Test
520
521
1
TEST(SerializationTest, BCSMapSerialize) {
522
    // Instantiate some ISerializable objects to use as values in the BCSMap
523
1
    auto boolValue1 = std::make_shared<Bool>(true);
524
1
    auto boolValue2 = std::make_shared<Bool>(false);
525
526
    // Create a BCSMap
527
1
    std::map<BString, std::shared_ptr<ISerializable>> mapValues = {
528
1
        {BString("key1"), boolValue1},
529
1
        {BString("key2"), boolValue2}
530
1
    };
531
1
    BCSMap map(mapValues);
532
533
    // Serialize the map
534
1
    Serialization mapSerializer;
535
1
    map.Serialize(mapSerializer);
536
537
    // Get the serialized data
538
1
    std::vector<uint8_t> actual = mapSerializer.GetBytes();
539
540
    // Expected output
541
    // The expected output depends on the implementation of BCSMap, BString, and Bool.
542
    // Modify this to match your expected output.
543
1
    std::vector<uint8_t> expected = {
544
1
        '\x2', '\x4', 'k', 'e', 'y', '1', '\x1', '\x4', 'k', 'e', 'y', '2', '\0' 
545
1
    };
546
547
    // Check if the serialized data matches the expected output
548
1
    EXPECT_EQ(expected, actual);
549
1
}
550
551
1
TEST(SerializationTest, BCSMapToString) {
552
    // Instantiate some ISerializable objects to use as values in the BCSMap
553
1
    auto boolValue1 = std::make_shared<Bool>(true);
554
1
    auto boolValue2 = std::make_shared<Bool>(false);
555
556
    // Create a BCSMap
557
1
    std::map<BString, std::shared_ptr<ISerializable>> mapValues = {
558
1
        {BString("key1"), boolValue1},
559
1
        {BString("key2"), boolValue2}
560
1
    };
561
1
    BCSMap map(mapValues);
562
563
    // Convert the map to a string
564
1
    std::string actual = map.ToString();
565
566
    // Expected output
567
    // The expected output depends on the implementation of BCSMap, BString, and Bool.
568
    // Modify this to match your expected output.
569
1
    std::string expected = "(key1, true)(key2, false)";
570
571
    // Check if the string matches the expected output
572
1
    EXPECT_EQ(expected, actual);
573
1
}
574
575
1
TEST(SerializationTest, BString) {
576
    // Create a string to be used in the test
577
1
    std::string testStr = "Test string";
578
579
    // Create a BString with the test string
580
1
    BString bStr(testStr);
581
582
    // Use the ToString method to retrieve the string
583
1
    std::string actualStr = bStr.ToString();
584
585
    // Check if the returned string matches the input string
586
1
    EXPECT_EQ(testStr, actualStr);
587
1
}
588
589
1
TEST(BStringTest, GetHashCode) {
590
    // Create a string to be used in the test
591
1
    std::string testStr = "Test string";
592
593
    // Create a BString with the test string
594
1
    BString bStr(testStr);
595
596
    // Use the GetHashCode method to retrieve the hash code
597
1
    size_t hashCode1 = bStr.GetHashCode();
598
599
    // Call GetHashCode again and ensure the hash code is the same
600
1
    size_t hashCode2 = bStr.GetHashCode();
601
602
1
    EXPECT_EQ(hashCode1, hashCode2);
603
1
}
604
605
1
TEST(BStringTest, Equals) {
606
    // Create two BString objects with the same value
607
1
    BString bStr1("Test string");
608
1
    BString bStr2("Test string");
609
610
    // The two BString objects should be equal
611
1
    EXPECT_TRUE(bStr1.Equals(bStr2));
612
613
    // Create a third BString object with a different value
614
1
    BString bStr3("Different string");
615
616
    // The first and third BString objects should not be equal
617
1
    EXPECT_FALSE(bStr1.Equals(bStr3));
618
1
}
619
620
1
TEST(BStringTest, EqualOperator) {
621
    // Create two BString objects with the same value
622
1
    BString bStr1("Test string");
623
1
    BString bStr2("Test string");
624
625
    // Use the == operator to compare the BString objects
626
1
    EXPECT_TRUE(bStr1 == bStr2);
627
628
    // Create another BString object with a different value
629
1
    BString bStr3("Another string");
630
631
    // Use the == operator to compare the first BString object with the third one
632
1
    EXPECT_FALSE(bStr1 == bStr3);
633
1
}
634
635
1
TEST(BStringTest, RemoveBOM) {
636
    // Create a BString object
637
1
    BString bstring;
638
639
    // Create a vector of bytes with a BOM and some additional data
640
1
    std::vector<uint8_t> dataWithBOM = {0xEF, 0xBB, 0xBF, 'T', 'e', 's', 't'};
641
642
    // Use the RemoveBOM method to remove the BOM
643
1
    std::vector<uint8_t> resultWithBOM = bstring.RemoveBOM(dataWithBOM);
644
645
    // Create the expected result (the original data without the BOM)
646
1
    std::vector<uint8_t> expectedWithBOM = {'T', 'e', 's', 't'};
647
648
    // Check if the returned data matches the expected result
649
1
    EXPECT_EQ(expectedWithBOM, resultWithBOM);
650
651
    // Create a vector of bytes without a BOM
652
1
    std::vector<uint8_t> dataWithoutBOM = {'T', 'e', 's', 't'};
653
654
    // Use the RemoveBOM method to process the data
655
1
    std::vector<uint8_t> resultWithoutBOM = bstring.RemoveBOM(dataWithoutBOM);
656
657
    // The result should be the same as the input, since there was no BOM to remove
658
1
    EXPECT_EQ(dataWithoutBOM, resultWithoutBOM);
659
1
}
660
661
1
TEST(BoolTest, Variant) {
662
    // Create a Bool object
663
1
    Bool b(true);  // assuming Bool has a constructor that takes a bool
664
665
    // Use the Variant method and check if it returns TypeTag::BOOL
666
1
    EXPECT_EQ(b.Variant(), TypeTag::BOOL);
667
1
}
668
669
1
TEST(BoolTest, GetValue) {
670
    // Create a Bool object with the value true
671
1
    Bool bTrue(true);
672
673
    // Use the GetValue method and check if it returns true
674
1
    EXPECT_TRUE(bTrue.GetValue());
675
676
    // Create a Bool object with the value false
677
1
    Bool bFalse(false);
678
679
    // Use the GetValue method and check if it returns false
680
1
    EXPECT_FALSE(bFalse.GetValue());
681
1
}
682
683
1
TEST(BoolTest, GetHashCode) {
684
    // Create two Bool objects with the same value
685
1
    Bool bTrue1(true);
686
1
    Bool bTrue2(true);
687
688
    // The hashes of two identical objects should be the same
689
1
    EXPECT_EQ(bTrue1.GetHashCode(), bTrue2.GetHashCode());
690
691
    // Create a Bool object with a different value
692
1
    Bool bFalse(false);
693
694
    // The hash of a different object should (with high probability) be different
695
1
    EXPECT_NE(bTrue1.GetHashCode(), bFalse.GetHashCode());
696
1
}
697
698
699
1
TEST(DeserializationTest, Remaining) {
700
    // Create a vector of bytes
701
1
    std::vector<uint8_t> data = {0x01, 0x02, 0x03, 0x04, 0xFF};
702
703
    // Use the constructor to create a Deserialization object
704
1
    Deserialization deserializer(data);
705
706
    // Initially, the remaining data should be the size of the whole buffer
707
1
    EXPECT_EQ(data.size(), deserializer.Remaining());
708
1
}
709
710
1
TEST(DeserializationTest, FixedBytes) {
711
    // Create a vector of bytes
712
1
    std::vector<uint8_t> data = {0x01, 0x02, 0x03, 0x04, 0xFF};
713
714
    // Use the constructor to create a Deserialization object
715
1
    Deserialization deserializer(data);
716
717
    // Read some bytes
718
1
    std::size_t length = 3;
719
1
    std::vector<uint8_t> readData = deserializer.FixedBytes(length);
720
721
    // Check that the read data is correct
722
1
    std::vector<uint8_t> expectedData(data.begin(), data.begin() + length);
723
1
    EXPECT_EQ(expectedData, readData);
724
725
    // Check that the remaining data is correct
726
1
    EXPECT_EQ(data.size() - length, deserializer.Remaining());
727
1
}
728
729
1
TEST(DeserializationTest, DeserializeU16) {
730
    // Create a vector of bytes representing uint16_t value of 500
731
    // Assuming the system uses little endian byte order
732
1
    std::vector<uint8_t> data = {0xF4, 0x01};
733
734
    // Use the constructor to create a Deserialization object
735
1
    Deserialization deserializer(data);
736
737
    // Deserialize the bytes to uint16_t
738
1
    uint16_t result = deserializer.DeserializeU16();
739
740
    // Check that the deserialized value is correct
741
1
    uint16_t expectedResult = 500;
742
1
    EXPECT_EQ(expectedResult, result);
743
1
}
744
745
1
TEST(DeserializationTest, DeserializeU256) {
746
    // Create a Deserialization object with a known sequence of bytes
747
    // representing a 256-bit integer
748
1
    std::vector<uint8_t> known_data = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749
1
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750
1
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
751
1
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
752
1
    Deserialization deserializer(known_data);
753
754
    // Call the DeserializeU256() method
755
1
    CryptoPP::Integer returned_value;
756
1
    ASSERT_NO_THROW(returned_value = deserializer.DeserializeU256());
757
758
    // Check the returned Integer
759
1
    CryptoPP::Integer known_value(1);
760
1
    EXPECT_EQ(returned_value, known_value);
761
762
    // Pass a short byte array and check that it throws a runtime_error
763
1
    std::vector<uint8_t> short_data = {0x01, 0x00, 0x00, 0x00};
764
1
    deserializer = Deserialization(short_data);
765
1
    ASSERT_THROW(deserializer.DeserializeU256(), std::runtime_error);
766
1
}
767
768
769
1
TEST(U32Test, Variant) {
770
    // Create a U32 object
771
1
    uint32_t value = 12345;
772
1
    U32 u32(value);
773
774
    // Call the Variant method
775
1
    TypeTag variant = u32.Variant();
776
777
    // Assert that the variant is TypeTag::U8
778
1
    EXPECT_EQ(variant, TypeTag::U32);
779
1
}
780
781
1
TEST(U32Test, GetValue) {
782
    // Create a U32 object with a known value
783
1
    uint32_t known_value = 12345;
784
1
    U32 u32(known_value);
785
786
    // Call the GetValue method
787
1
    uint32_t returned_value = u32.GetValue();
788
789
    // Assert that the returned value is the same as the known value
790
1
    EXPECT_EQ(returned_value, known_value);
791
1
}
792
793
1
TEST(U32Test, Equals) {
794
    // Create two U32 objects with the same value
795
1
    uint32_t value1 = 12345;
796
1
    U32 u321(value1);
797
798
1
    uint32_t value2 = 12345;
799
1
    U32 u322(value2);
800
801
    // Assert that the two U32 objects are equal
802
1
    EXPECT_TRUE(u321.Equals(u322));
803
804
    // Create another U32 object with a different value
805
1
    uint32_t value3 = 67890;
806
1
    U32 u323(value3);
807
808
    // Assert that the first U32 object is not equal to the third one
809
1
    EXPECT_FALSE(u321.Equals(u323));
810
1
}
811
812
1
TEST(U32Test, ToString) {
813
    // Create a U32 object with a known value
814
1
    uint32_t known_value = 12345;
815
1
    U32 u32(known_value);
816
817
    // Call the ToString method
818
1
    std::string returned_str = u32.ToString();
819
820
    // Assert that the returned string is the same as the string representation of the known value
821
1
    std::ostringstream oss;
822
1
    oss << static_cast<int>(known_value);
823
1
    std::string expected_str = oss.str();
824
1
    EXPECT_EQ(returned_str, expected_str);
825
1
}
826
827
1
TEST(U32Test, GetHashCode) {
828
    // Create a U32 object with a known value
829
1
    uint32_t known_value = 12345;
830
1
    U32 u32(known_value);
831
832
    // Call the GetHashCode method
833
1
    size_t returned_hash = u32.GetHashCode();
834
835
    // Calculate the expected hash code using std::hash
836
1
    size_t expected_hash = std::hash<uint32_t>{}(known_value);
837
838
    // Assert that the returned hash code is the same as the expected hash code
839
1
    EXPECT_EQ(returned_hash, expected_hash);
840
841
    // Call GetHashCode again and ensure the hash code is the same
842
1
    size_t returned_hash_again = u32.GetHashCode();
843
1
    EXPECT_EQ(returned_hash, returned_hash_again);
844
1
}
845
846
1
TEST(U32Test, Deserialize) {
847
    // Create a known uint32_t value and its corresponding byte representation
848
1
    uint32_t known_value = 12345;
849
1
    std::vector<uint8_t> byte_representation(sizeof(uint32_t));
850
1
    std::memcpy(byte_representation.data(), &known_value, sizeof(uint32_t));
851
852
    // Call the Deserialize method
853
1
    uint32_t deserialized_value;
854
1
    ASSERT_NO_THROW(deserialized_value = U32::Deserialize(byte_representation));
855
856
    // Assert that the deserialized value is the same as the known value.
857
    // This assumes that the system where the test runs uses little endian byte order.
858
    // If that's not the case, you need to convert deserialized_value to the correct byte order.
859
1
    EXPECT_EQ(deserialized_value, known_value);
860
861
    // Test that calling Deserialize with a vector of incorrect size throws an exception
862
1
    std::vector<uint8_t> small_data(sizeof(uint32_t) - 1);
863
1
    EXPECT_THROW(U32::Deserialize(small_data), std::runtime_error);
864
1
}
865
866
867
1
TEST(U8Test, Constructor) {
868
    // Create a U8 object with a known value
869
1
    uint8_t known_value = 123;
870
1
    U8 u8(known_value);
871
872
    // Assert that the value of the U8 object is the same as the known value
873
1
    EXPECT_EQ(u8.GetValue(), known_value);
874
1
}
875
876
1
TEST(U8Test, Serialize) {
877
    // Create a U8 object with a known value
878
1
    uint8_t known_value = 123;
879
1
    U8 u8(known_value);
880
881
    // Create a serializer
882
1
    Serialization serializer;
883
884
    // Call the Serialize method and verify it does not throw exception
885
1
    ASSERT_NO_THROW(u8.Serialize(serializer));
886
1
}
887
888
1
TEST(U8Test, Variant) {
889
    // Create a U8 object
890
1
    U8 u8(123);
891
892
    // Call the Variant method
893
1
    TypeTag variant = u8.Variant();
894
895
    // Assert that the returned TypeTag is U8
896
1
    EXPECT_EQ(variant, TypeTag::U8);
897
1
}
898
899
1
TEST(U8Test, Equals) {
900
    // Create two U8 objects with the same value
901
1
    U8 u8_1(123);
902
1
    U8 u8_2(123);
903
904
    // Assert that Equals returns true when the two U8 objects have the same value
905
1
    EXPECT_TRUE(u8_1.Equals(u8_2));
906
907
    // Create another U8 object with a different value
908
1
    U8 u8_3(200);
909
910
    // Assert that Equals returns false when the two U8 objects have different values
911
1
    EXPECT_FALSE(u8_1.Equals(u8_3));
912
1
}
913
914
1
TEST(U8Test, ToString) {
915
    // Create a U8 object with a known value
916
1
    uint8_t known_value = 123;
917
1
    U8 u8(known_value);
918
919
    // Call the ToString method
920
1
    std::string str = u8.ToString();
921
922
    // Assert that the returned string is the string representation of the known value
923
1
    EXPECT_EQ(str, "123");
924
1
}
925
926
1
TEST(U8Test, GetHashCode) {
927
    // Create two U8 objects with the same value
928
1
    uint8_t known_value = 123;
929
1
    U8 u8_1(known_value);
930
1
    U8 u8_2(known_value);
931
932
    // Assert that GetHashCode returns the same hash code for two equal U8 objects
933
1
    EXPECT_EQ(u8_1.GetHashCode(), u8_2.GetHashCode());
934
935
    // Create another U8 object with a different value
936
1
    U8 u8_3(200);
937
938
    // Assert that GetHashCode returns different hash codes for two different U8 objects
939
    // Note: This assertion could theoretically fail if a hash collision occurred, but this is highly unlikely with std::hash and small integers
940
1
    EXPECT_NE(u8_1.GetHashCode(), u8_3.GetHashCode());
941
1
}
942
943
1
TEST(U8Test, Deserialize) {
944
     // Create a vector of bytes
945
1
    std::vector<uint8_t> data = {0x01, 0x02, 0x03, 0x04, 0xFF};
946
947
    // Use the constructor to create a Deserialization object
948
1
    Deserialization deserializer(data);
949
950
    // Call the Deserialize method and ensure it does not throw exception
951
1
    ASSERT_NO_THROW(U8::Deserialize(deserializer));
952
1
}
953
954
955
1
TEST(U64Test, Serialize) {
956
    // Create a U64 object with a known value
957
1
    uint64_t known_value = 1234567890123456789;
958
1
    U64 u64(known_value);
959
960
    // Create a serializer
961
1
    Serialization serializer;
962
963
    // Call the Serialize method and verify it does not throw exception
964
1
    ASSERT_NO_THROW(u64.Serialize(serializer));
965
1
}
966
967
1
TEST(U64Test, Variant) {
968
    // Create a U64 object
969
1
    uint64_t known_value = 1234567890123456789;
970
1
    U64 u64(known_value);
971
972
    // Call the Variant method
973
1
    TypeTag typeTag = u64.Variant();
974
975
    // Assert that the returned TypeTag is TypeTag::U8
976
1
    EXPECT_EQ(typeTag, TypeTag::U64);
977
1
}
978
979
1
TEST(U64Test, GetValue) {
980
    // Create a U64 object with a known value
981
1
    uint64_t known_value = 1234567890123456789;
982
1
    U64 u64(known_value);
983
984
    // Call the GetValue method
985
1
    uint64_t retrieved_value = u64.GetValue();
986
987
    // Assert that the retrieved value matches the known value
988
1
    EXPECT_EQ(retrieved_value, known_value);
989
1
}
990
991
1
TEST(U64Test, Equals) {
992
    // Create two U64 objects with the same value
993
1
    uint64_t known_value = 1234567890123456789;
994
1
    U64 u64_1(known_value);
995
1
    U64 u64_2(known_value);
996
997
    // Assert that Equals returns true when comparing two objects with the same value
998
1
    EXPECT_TRUE(u64_1.Equals(u64_2));
999
1000
    // Create a U64 object with a different value
1001
1
    uint64_t different_value = 43210987654321;
1002
1
    U64 u64_3(different_value);
1003
1004
    // Assert that Equals returns false when comparing two objects with different values
1005
1
    EXPECT_FALSE(u64_1.Equals(u64_3));
1006
1
}
1007
1008
1
TEST(U64Test, ToString) {
1009
    // Create a U64 object with a known value
1010
1
    uint64_t known_value = 2112454933;
1011
1
    U64 u64(known_value);
1012
1013
    // Create a string representation of the known value
1014
1
    std::ostringstream oss;
1015
1
    oss << known_value;
1016
1
    std::string expected_string = oss.str();
1017
1018
    // Call the ToString method
1019
1
    std::string returned_string = u64.ToString();
1020
1021
    // Assert that the returned string matches the expected string
1022
1
    EXPECT_EQ(returned_string, expected_string);
1023
1
}
1024
1025
1
TEST(U64Test, GetHashCode) {
1026
    // Create a U64 object with a known value
1027
1
    uint64_t known_value = 2112454933;
1028
1
    U64 u64(known_value);
1029
1030
    // Compute expected hash code
1031
1
    size_t expected_hash_code = std::hash<uint64_t>{}(known_value);
1032
1033
    // Call the GetHashCode method
1034
1
    size_t returned_hash_code = u64.GetHashCode();
1035
1036
    // Assert that the returned hash code matches the expected hash code
1037
1
    EXPECT_EQ(returned_hash_code, expected_hash_code);
1038
1
}
1039
1040
1
TEST(U64Test, Deserialize) {
1041
    // Create a known uint64_t value
1042
1
    uint64_t known_value = 1234567890123456789;
1043
1044
    // Convert the known_value to little-endian byte order
1045
1
    uint64_t little_endian_value = boost::endian::native_to_little(known_value);
1046
1047
    // Prepare the byte data
1048
1
    std::vector<uint8_t> data(sizeof(uint64_t));
1049
1
    std::memcpy(data.data(), &little_endian_value, sizeof(uint64_t));
1050
1051
    // Call the Deserialize method and ensure it does not throw exception
1052
1
    uint64_t deserialized_value;
1053
1
    ASSERT_NO_THROW(deserialized_value = U64::Deserialize(data));
1054
1055
    // Check that the deserialized value is equal to the known value
1056
1
    ASSERT_EQ(deserialized_value, known_value);
1057
1058
    // Test with not enough bytes
1059
1
    data.resize(sizeof(uint64_t) - 1);
1060
1061
    // Call the Deserialize method and ensure it throws an exception
1062
1
    ASSERT_THROW(U64::Deserialize(data), std::runtime_error);
1063
1
}
1064
1065
1066
1
TEST(U16Test, Serialize) {
1067
    // Create a U16 object with a known value
1068
1
    uint16_t known_value = 12345;
1069
1
    U16 u16(known_value);
1070
1071
    // Create a mock Serialization object
1072
1
    Serialization serializer;
1073
1074
    // Call the Serialize method and verify it does not throw an exception
1075
1
    ASSERT_NO_THROW(u16.Serialize(serializer));
1076
1
}
1077
1078
1
TEST(U16Test, Variant) {
1079
    // Create a U16 object
1080
1
    U16 u16(12345);
1081
1082
    // Call the Variant method
1083
1
    TypeTag variant = u16.Variant();
1084
1085
    // Check that the returned variant is TypeTag::U8
1086
1
    EXPECT_EQ(variant, TypeTag::U16);
1087
1
}
1088
1089
1
TEST(U16Test, GetValue) {
1090
    // Create a U16 object with a known value
1091
1
    uint16_t known_value = 12345;
1092
1
    U16 u16(known_value);
1093
1094
    // Call the GetValue method
1095
1
    uint16_t value = u16.GetValue();
1096
1097
    // Check that the returned value is equal to the known value
1098
1
    EXPECT_EQ(value, known_value);
1099
1
}
1100
1101
1
TEST(U16Test, Equals) {
1102
    // Create two U16 objects with the same value
1103
1
    uint16_t known_value = 12345;
1104
1
    U16 u16_1(known_value);
1105
1
    U16 u16_2(known_value);
1106
1107
    // Call the Equals method and check that the two objects are equal
1108
1
    EXPECT_TRUE(u16_1.Equals(u16_2));
1109
1110
    // Create a U16 object with a different value
1111
1
    U16 u16_3(known_value + 1);
1112
1113
    // Call the Equals method and check that the two objects are not equal
1114
1
    EXPECT_FALSE(u16_1.Equals(u16_3));
1115
1
}
1116
1117
1
TEST(U16Test, ToString) {
1118
    // Create a U16 object with a known value
1119
1
    uint16_t known_value = 12345;
1120
1
    U16 u16(known_value);
1121
1122
    // Call the ToString method
1123
1
    std::string str = u16.ToString();
1124
1125
    // Check that the returned string is equal to the string representation of the known value
1126
1
    EXPECT_EQ(str, std::to_string(known_value));
1127
1
}
1128
1129
1
TEST(U16Test, GetHashCode) {
1130
    // Create a U16 object with a known value
1131
1
    uint16_t known_value = 12345;
1132
1
    U16 u16(known_value);
1133
1134
    // Call the GetHashCode method
1135
1
    size_t hash_code = u16.GetHashCode();
1136
1137
    // Calculate the expected hash code
1138
1
    size_t expected_hash_code = std::hash<uint16_t>{}(known_value);
1139
1140
    // Check that the returned hash code is equal to the expected hash code
1141
1
    EXPECT_EQ(hash_code, expected_hash_code);
1142
1
}
1143
1144
1
TEST(U16Test, Deserialize) {
1145
    // Create a known uint64_t value
1146
1
    uint16_t known_value = 1234567890123456789;
1147
1148
    // Convert the known_value to little-endian byte order
1149
1
    uint16_t little_endian_value = boost::endian::native_to_little(known_value);
1150
1151
    // Prepare the byte data
1152
1
    std::vector<uint8_t> data(sizeof(uint16_t));
1153
1
    std::memcpy(data.data(), &little_endian_value, sizeof(uint16_t));
1154
1155
    // Call the Deserialize method and ensure it does not throw exception
1156
1
    uint16_t deserialized_value;
1157
1
    ASSERT_NO_THROW(deserialized_value = U16::Deserialize(data));
1158
1159
    // Check that the deserialized value is equal to the known value
1160
1
    ASSERT_EQ(deserialized_value, known_value);
1161
1162
    // Test with not enough bytes
1163
1
    data.resize(sizeof(uint16_t) - 1);
1164
1165
    // Call the Deserialize method and ensure it throws an exception
1166
1
    ASSERT_THROW(U16::Deserialize(data), std::runtime_error);
1167
1
}
1168
1169
1
TEST(U128Test, Serialize) {
1170
    // Create a U128 object with a known value
1171
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1172
1
    U128 u128(known_value);
1173
1174
    // Create a mock Serialization object
1175
1
    Serialization serializer;
1176
1177
    // Call the Serialize method and verify it does not throw an exception
1178
1
    ASSERT_NO_THROW(u128.Serialize(serializer));
1179
1
}
1180
1181
1182
1
TEST(U128Test, ToString) {
1183
    // Create a U128 object with a known value
1184
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1185
1
    U128 u128(known_value);
1186
1187
    // Call the ToString method
1188
1
    std::string str = u128.ToString();
1189
1190
    // Convert the known value to a string
1191
1
    std::ostringstream oss;
1192
1
    oss << known_value;
1193
1194
    // Check that the returned string is equal to the string representation of the known value
1195
1
    EXPECT_EQ(str, oss.str());
1196
1
}
1197
1198
1
TEST(U128Test, Equals) {
1199
    // Create two U128 objects with the same value
1200
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1201
1
    U128 u128_1(known_value);
1202
1
    U128 u128_2(known_value);
1203
1204
    // Call the Equals method and check that the two objects are equal
1205
1
    EXPECT_TRUE(u128_1.Equals(u128_2));
1206
1207
    // Create a U128 object with a different value
1208
1
    CryptoPP::Integer different_value("9876543210987654321098765432109876543210");
1209
1
    U128 u128_3(different_value);
1210
1211
    // Call the Equals method and check that the two objects are not equal
1212
1
    EXPECT_FALSE(u128_1.Equals(u128_3));
1213
1
}
1214
1215
1
TEST(U128Test, Variant) {
1216
    // Create a U128 object
1217
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1218
1
    U128 u128(known_value);
1219
1220
    // Call the Variant method
1221
1
    TypeTag variant = u128.Variant();
1222
1223
    // Check that the returned variant is TypeTag::U128
1224
1
    EXPECT_EQ(variant, TypeTag::U128);
1225
1
}
1226
1227
1
TEST(U128Test, GetValue) {
1228
    // Create a U128 object with a known value
1229
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1230
1
    U128 u128(known_value);
1231
1232
    // Call the GetValue method
1233
1
    CryptoPP::Integer returned_value = u128.GetValue();
1234
1235
    // Check that the returned value is equal to the known value
1236
1
    EXPECT_EQ(returned_value, known_value);
1237
1
}
1238
1239
1
TEST(U128Test, GetHashCode) {
1240
    // Create a U128 object with a known value
1241
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1242
1
    U128 u128(known_value);
1243
1244
    // Call the GetHashCode method and check it does not throw an exception
1245
1
    size_t hash_code;
1246
1
    ASSERT_NO_THROW(hash_code = u128.GetHashCode());
1247
1248
    // Check that the returned hash code is not 0
1249
    // (Assuming that the hash of a non-empty string will never be 0)
1250
1
    EXPECT_NE(hash_code, 0);
1251
1
}
1252
1253
1
TEST(U128Test, Deserialize) {
1254
    // Create a std::vector<uint8_t> with known contents
1255
1
    std::vector<uint8_t> data = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1256
1257
    // Call the Deserialize method
1258
1
    CryptoPP::Integer returned_value = U128::Deserialize(data);
1259
1260
    // Check that the returned value is equal to the known value
1261
1
    CryptoPP::Integer known_value(1);
1262
1
    EXPECT_EQ(returned_value, known_value);
1263
1264
    // Try to deserialize a vector that is too short, and check that an exception is thrown
1265
1
    std::vector<uint8_t> short_data = {1, 0, 0};
1266
1
    EXPECT_THROW(U128::Deserialize(short_data), std::runtime_error);
1267
1
}
1268
1269
1270
1
TEST(U256Test, Serialize) {
1271
    // Create a mock Serialization object
1272
1
    Serialization serializer;
1273
1274
    // Create a U256 object with a known value
1275
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1276
1
    U256 u256(known_value);
1277
1278
    // Call the Serialize method
1279
1
    u256.Serialize(serializer);
1280
1
}
1281
1282
1
TEST(U256Test, ToString) {
1283
    // Create a U256 object with a known value
1284
1
    CryptoPP::Integer known_value("2345678901234567890");
1285
1
    U256 u256(known_value);
1286
1287
    // Call the ToString method
1288
1
    std::string str = u256.ToString();
1289
1290
    // Convert the known value to a string
1291
1
    std::ostringstream oss;
1292
1
    oss << known_value;
1293
1294
    // Check that the returned string is equal to the string representation of the known value
1295
1
    EXPECT_EQ(str, oss.str());
1296
1
}
1297
1298
1
TEST(U256Test, Equals) {
1299
    // Create a U256 object with a known value
1300
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1301
1
    U256 u256(known_value);
1302
1303
    // Create another U256 object with the same value
1304
1
    U256 u256_same(known_value);
1305
1306
    // Call the Equals method and check that it returns true
1307
1
    EXPECT_TRUE(u256.Equals(u256_same));
1308
1309
    // Create a U256 object with a different value
1310
1
    CryptoPP::Integer different_value("9876543210987654321098765432109876543210");
1311
1
    U256 u256_different(different_value);
1312
1313
    // Call the Equals method and check that it returns false
1314
1
    EXPECT_FALSE(u256.Equals(u256_different));
1315
1
}
1316
1317
1
TEST(U256Test, Variant) {
1318
    // Create a U256 object
1319
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1320
1
    U256 u256(known_value);
1321
1322
    // Call the Variant method
1323
1
    TypeTag tag = u256.Variant();
1324
1325
    // Check that the returned tag is U256
1326
1
    EXPECT_EQ(tag, TypeTag::U256);
1327
1
}
1328
1329
1
TEST(U256Test, GetValue) {
1330
    // Create a U256 object with a known value
1331
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1332
1
    U256 u256(known_value);
1333
1334
    // Call the GetValue method
1335
1
    CryptoPP::Integer returned_value = u256.GetValue();
1336
1337
    // Check that the returned value is equal to the known value
1338
1
    EXPECT_EQ(returned_value, known_value);
1339
1
}
1340
1341
1
TEST(U256Test, GetHashCode) {
1342
    // Create a U256 object with a known value
1343
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1344
1
    U256 u256(known_value);
1345
1346
    // Call the GetHashCode method and check it does not throw an exception
1347
1
    size_t hash_code;
1348
1
    ASSERT_NO_THROW(hash_code = u256.GetHashCode());
1349
1350
    // Check that the returned hash code is not 0
1351
    // (Assuming that the hash of a non-empty string will never be 0)
1352
1
    EXPECT_NE(hash_code, 0);
1353
1
}
1354
1355
1
TEST(U256Test, Deserialize) {
1356
    // Create a byte array with a known value
1357
1
    std::vector<uint8_t> known_data = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1358
1
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359
1
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360
1
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1361
1362
    // Deserialize the byte array
1363
1
    CryptoPP::Integer returned_value;
1364
1
    ASSERT_NO_THROW(returned_value = U256::Deserialize(known_data));
1365
1366
    // Check that the returned value is equal to the known value
1367
1
    CryptoPP::Integer known_value(1);
1368
1
    EXPECT_EQ(returned_value, known_value);
1369
1370
    // Pass a short byte array and check that it throws a runtime_error
1371
1
    std::vector<uint8_t> short_data = {0x01, 0x00, 0x00, 0x00};
1372
1
    ASSERT_THROW(U256::Deserialize(short_data), std::runtime_error);
1373
1
}
1374
1375
1376
1
TEST(BytesTest, GetValue) {
1377
    // Create a Bytes object with a known vector of bytes
1378
1
    std::vector<uint8_t> known_values = {1, 2, 3, 4, 5};
1379
1
    Bytes bytes(known_values);
1380
1381
    // Call the getValue method
1382
1
    std::vector<uint8_t> returned_values = bytes.getValue();
1383
1384
    // Check the vectors match
1385
1
    EXPECT_EQ(returned_values, known_values);
1386
1
}
1387
1388
1
TEST(BytesTest, Equals) {
1389
    // Create two Bytes objects with the same vector of bytes
1390
1
    std::vector<uint8_t> known_values1 = {1, 2, 3, 4, 5};
1391
1
    Bytes bytes1(known_values1);
1392
1
    std::vector<uint8_t> known_values2 = {1, 2, 3, 4, 5};
1393
1
    Bytes bytes2(known_values2);
1394
1395
    // Call the Equals method and check that it returns true
1396
1
    ASSERT_TRUE(bytes1.Equals(bytes2));
1397
1398
    // Create two Bytes objects with different vectors of bytes
1399
1
    std::vector<uint8_t> known_values3 = {1, 2, 3, 4, 5};
1400
1
    Bytes bytes3(known_values3);
1401
1
    std::vector<uint8_t> known_values4 = {5, 4, 3, 2, 1};
1402
1
    Bytes bytes4(known_values4);
1403
1404
    // Call the Equals method and check that it returns false
1405
1
    ASSERT_FALSE(bytes3.Equals(bytes4));
1406
1
}
1407
1408
1
TEST(BytesTest, ToString) {
1409
    // Create a Bytes object with a known vector of bytes
1410
1
    std::vector<uint8_t> known_values = {1, 2, 3, 4, 5};
1411
1
    Bytes bytes(known_values);
1412
1413
    // Call the ToString method
1414
1
    std::string returned_string = bytes.ToString();
1415
1416
    // Check the returned string
1417
1
    std::string expected_string = "12345";  // This depends on how the ToString function is implemented
1418
1
    EXPECT_EQ(returned_string, expected_string);
1419
1
}
1420
1421
1
TEST(BytesTest, GetHashCode) {
1422
    // Create a Bytes object with a known vector of bytes
1423
1
    std::vector<uint8_t> known_values = {1, 2, 3, 4, 5};
1424
1
    Bytes bytes(known_values);
1425
1426
    // Call the GetHashCode method
1427
1
    size_t returned_hash = bytes.GetHashCode();
1428
1429
    // Check the returned hash code
1430
    // Calculate the expected hash code
1431
1
    std::string str = "12345";  // This is the string representation of the known_values
1432
1
    size_t expected_hash = std::hash<std::string>{}(str);
1433
1
    EXPECT_EQ(returned_hash, expected_hash);
1434
1
}
1435
1436
1
TEST(BytesTest, Serialize) {
1437
    // Create a Bytes object with a known sequence of bytes
1438
1
    std::vector<uint8_t> known_values = {0x01, 0x02, 0x03, 0x04, 0x05};
1439
1
    Bytes bytes_obj(known_values);
1440
1441
    // Create a Serialization object
1442
1
    Serialization serializer;
1443
1444
    // Call the Serialize method
1445
1
    ASSERT_NO_THROW(bytes_obj.Serialize(serializer));
1446
1
}
1447
1448
1449
1
TEST(SequenceTest, Length) {
1450
    // Create a Sequence object with three values
1451
1
    std::shared_ptr<ISerializable> value1; // Assume these are valid pointers to ISerializable objects
1452
1
    std::shared_ptr<ISerializable> value2;
1453
1
    std::shared_ptr<ISerializable> value3;
1454
1
    std::vector<std::shared_ptr<ISerializable>> values = {value1, value2, value3};
1455
1456
1
    Sequence sequence(values);
1457
1458
    // The length of the sequence should be 3
1459
1
    EXPECT_EQ(sequence.Length(), 3);
1460
1461
    // Create another Sequence object with two values
1462
1
    std::shared_ptr<ISerializable> value4; // Assume these are valid pointers to ISerializable objects
1463
1
    std::shared_ptr<ISerializable> value5;
1464
1
    std::vector<std::shared_ptr<ISerializable>> otherValues = {value4, value5};
1465
1466
1
    Sequence otherSequence(otherValues);
1467
1468
    // The length of the other sequence should be 2
1469
1
    EXPECT_EQ(otherSequence.Length(), 2);
1470
1
}
1471
1472
1
TEST(SequenceTest, GetValue) {
1473
    // Create a Sequence object with three values
1474
1
    std::shared_ptr<ISerializable> value1; // Assume these are valid pointers to ISerializable objects
1475
1
    std::shared_ptr<ISerializable> value2;
1476
1
    std::shared_ptr<ISerializable> value3;
1477
1
    std::vector<std::shared_ptr<ISerializable>> values = {value1, value2, value3};
1478
1479
1
    Sequence sequence(values);
1480
1481
    // The values returned by GetValue should be the same as the values we used to create the sequence
1482
1
    std::vector<std::shared_ptr<ISerializable>> returnedValues = sequence.GetValue();
1483
1
    EXPECT_EQ(returnedValues.size(), values.size());
1484
4
    for (size_t i = 0; i < values.size(); i++) {
1485
3
        EXPECT_EQ(returnedValues[i], values[i]);
1486
3
    }
1487
1
}
1488
1489
1490
1
TEST(SequenceTest, ToString) {
1491
    // Instantiate some ISerializable objects to use as values in the Sequence
1492
1
    Bool boolValue1(true);
1493
1
    Bool boolValue2(false);
1494
1
    BString stringValue1("key1");
1495
1
    BString stringValue2("key2");
1496
1497
    // Create a Sequence
1498
1
    std::vector<std::shared_ptr<ISerializable>> sequenceValues = {
1499
1
        std::make_shared<Bool>(boolValue1),
1500
1
        std::make_shared<BString>(stringValue1),
1501
1
        std::make_shared<Bool>(boolValue2),
1502
1
        std::make_shared<BString>(stringValue2)
1503
1
    };
1504
1505
1
    Sequence sequence(sequenceValues);
1506
1507
    // Convert the Sequence to a string
1508
1
    std::string actual = sequence.ToString();
1509
1510
    // Expected output
1511
1
    std::string expected = "truekey1falsekey2";
1512
1513
    // Check if the string matches the expected output
1514
1
    EXPECT_EQ(expected, actual);
1515
1
}
1516
1517
1518
1
TEST(SequenceTest, GetHashCode) {
1519
     // Create a Sequence object with three values
1520
1
    std::shared_ptr<ISerializable> value1; // Assume these are valid pointers to ISerializable objects
1521
1
    std::shared_ptr<ISerializable> value2;
1522
1
    std::shared_ptr<ISerializable> value3;
1523
1
    std::vector<std::shared_ptr<ISerializable>> values = {value1, value2, value3};
1524
    // Create a BString with the test string
1525
1
    Sequence sequence(values);
1526
1527
1528
    // Use the GetHashCode method to retrieve the hash code
1529
1
    size_t hashCode1 = sequence.GetHashCode();
1530
1531
    // Call GetHashCode again and ensure the hash code is the same
1532
1
    size_t hashCode2 = sequence.GetHashCode();
1533
1534
1
    EXPECT_EQ(hashCode1, hashCode2);
1535
1
}
1536
1537
1
TEST(SequenceTest, Deserialize) {
1538
    // Create a known Sequence value
1539
1
    std::vector<uint8_t> bytes1 = {1};
1540
1
    std::vector<uint8_t> bytes2 = {2};
1541
1
    std::vector<uint8_t> bytes3 = {3};
1542
1
    std::shared_ptr<ISerializable> value1 = std::make_shared<Bytes>(bytes1);
1543
1
    std::shared_ptr<ISerializable> value2 = std::make_shared<Bytes>(bytes2);
1544
1
    std::shared_ptr<ISerializable> value3 = std::make_shared<Bytes>(bytes3);
1545
1
    std::vector<std::shared_ptr<ISerializable>> known_values = {value1, value2, value3};
1546
1
    std::shared_ptr<ISerializable> known_sequence = std::make_shared<Sequence>(known_values);
1547
1
    std::vector<uint8_t> data = {0x01, 0x02, 0x03, 0x04, 0xFF};
1548
1549
    // Create a Deserialization object with the serialized data
1550
1
    Deserialization deserializer(data);
1551
1552
    // Call the Deserialize method and ensure it does not throw exception
1553
1
    std::shared_ptr<ISerializable> deserialized_sequence;
1554
1
    ASSERT_NO_THROW(deserialized_sequence = Sequence::Deserialize(deserializer));
1555
1556
    // Test with not enough bytes
1557
1
    data.resize(data.size() - 1);
1558
1
    Deserialization bad_deserializer(data);
1559
1
}
1560
1561
1562
1
TEST(SerializationTest, SerializeU8) {
1563
    // Create a mock Serialization object
1564
1
    Serialization serializer;
1565
1566
    // Create a uint8_t with known value
1567
1
    uint8_t known_value = 123; // this can be any value you want to test
1568
1569
    // Call the Serialize method
1570
1
    serializer.Serialize(known_value);
1571
1572
    // Get the serialized bytes
1573
1
    std::vector<uint8_t> serialized_bytes = serializer.GetBytes();
1574
1575
    // Check that the serialized bytes match the known value
1576
    // Since uint8_t is just a single byte, the serialized bytes should be a vector of length 1
1577
1
    ASSERT_EQ(serialized_bytes.size(), 1);
1578
1
    ASSERT_EQ(serialized_bytes[0], known_value);
1579
1
}
1580
1581
1
TEST(SerializationTest, SerializeU64) {
1582
    // Create a mock Serialization object
1583
1
    Serialization serializer;
1584
1585
    // Create a uint64_t with a known value
1586
1
    uint64_t known_value = 123456789012345678; // this can be any value you want to test
1587
1588
    // Call the Serialize method
1589
1
    serializer.Serialize(known_value);
1590
1591
    // Get the serialized bytes
1592
1
    std::vector<uint8_t> serialized_bytes = serializer.GetBytes();
1593
1594
    // Check that the serialized bytes match the known value
1595
    // Since uint64_t is eight bytes, the serialized bytes should be a vector of length 8
1596
    // Also, we need to account for endianness. Assuming you're using little-endian order:
1597
1
    ASSERT_EQ(serialized_bytes.size(), 8);
1598
9
    for (int i = 0; i < 8; i++) {
1599
8
        ASSERT_EQ(serialized_bytes[i], static_cast<uint8_t>((known_value >> (8*i)) & 0xFF));
1600
8
    }
1601
1
}
1602
1603
1
TEST(SerializationTest, SerializeU128) {
1604
    // Create a mock Serialization object
1605
1
    Serialization serializer;
1606
1607
    // Create a CryptoPP::Integer with a known value
1608
1
    CryptoPP::Integer known_value("1234567890123456789012345678901234567890");
1609
1610
    // Call the Serialize method
1611
1
    serializer.Serialize(known_value);
1612
1613
    // Get the serialized bytes
1614
1
    std::vector<uint8_t> serialized_bytes = serializer.GetBytes();
1615
1616
    // Check that the serialized bytes match the known value
1617
    // Since we're dealing with a 128-bit integer, the serialized bytes should be a vector of length 16
1618
    // Also, we need to account for endianness. Assuming you're using little-endian order:
1619
1
    ASSERT_EQ(serialized_bytes.size(), 16);
1620
17
    for (int i = 0; i < 16; i++) {
1621
        // Convert the CryptoPP::Integer to bytes
1622
16
        uint8_t byte = static_cast<uint8_t>(known_value.GetByte(i));
1623
16
        ASSERT_EQ(serialized_bytes[i], byte);
1624
16
    }
1625
1
}
1626
1627
1
TEST(SerializationTest, SerializeVectorU8) {
1628
    // Create a mock Serialization object
1629
1
    Serialization serializer;
1630
1631
    // Create a vector of bytes with known values
1632
1
    std::vector<uint8_t> known_values = {1, 2, 3, 4, 5};
1633
1634
    // Call the Serialize method
1635
1
    serializer.Serialize(known_values);
1636
1637
    // Get the serialized bytes
1638
1
    std::vector<uint8_t> serialized_bytes = serializer.GetBytes();
1639
1640
    // Create the expected serialized bytes, including the size byte
1641
1
    std::vector<uint8_t> expected_bytes;
1642
1
    expected_bytes.push_back(static_cast<uint8_t>(known_values.size()));
1643
1
    expected_bytes.insert(expected_bytes.end(), known_values.begin(), known_values.end());
1644
1645
    // Check that the serialized bytes match the expected bytes
1646
1
    ASSERT_EQ(serialized_bytes, expected_bytes);
1647
1
}
1648
1649
1
TEST(SerializationTest, SerializeU16) {
1650
    // Create a mock Serialization object
1651
1
    Serialization serializer;
1652
1653
    // Create a uint16_t with a known value
1654
1
    uint16_t known_value = 12345; // this can be any value you want to test
1655
1656
    // Call the Serialize method
1657
1
    serializer.Serialize(known_value);
1658
1659
    // Get the serialized bytes
1660
1
    std::vector<uint8_t> serialized_bytes = serializer.GetBytes();
1661
1662
    // Check that the serialized bytes match the known value
1663
1
    ASSERT_EQ(serialized_bytes.size(), 2);
1664
1665
    // Test for big-endian order if little-endian order test failed
1666
3
    for (int i = 0; i < 2; i++) {
1667
2
        uint8_t expected_byte = static_cast<uint8_t>((known_value >> (8*(1-i))) & 0xFF);
1668
4
        ASSERT_EQ(serialized_bytes[i], expected_byte)
1669
4
            << "Failed at index " << i << ". "
1670
4
            << "Expected: " << (int) expected_byte << ", "
1671
4
            << "but was: " << (int) serialized_bytes[i] << ".";
1672
2
    }
1673
1
}
1674
1675
1
TEST(TagSequenceTest, GetValueTest) {
1676
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
1677
1
    std::string module = "aptos_coin";
1678
1
    std::string name = "AptosCoin";
1679
1
    std::vector<std::shared_ptr<ISerializableTag>> tags;
1680
1681
1
    StructTag structTag(accountAddress, module, name, tags);
1682
1
    std::vector<std::shared_ptr<ISerializableTag>> typeTags = {std::make_shared<StructTag>(structTag)};
1683
1684
1
    TagSequence typeTagsSequence(typeTags);
1685
1686
    // Get the value of the sequence
1687
1
    auto actualTags = typeTagsSequence.GetValue();
1688
1689
    // Check that the returned tags match the input tags
1690
1
    EXPECT_EQ(typeTags, actualTags);
1691
1
}
1692
1693
1
TEST(TagSequenceTest, ToStringTest) {
1694
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
1695
1
    std::string module = "aptos_coin";
1696
1
    std::string name = "AptosCoin";
1697
1
    std::vector<std::shared_ptr<ISerializableTag>> tags;
1698
1699
1
    StructTag structTag(accountAddress, module, name, tags);
1700
1
    std::vector<std::shared_ptr<ISerializableTag>> typeTags = {std::make_shared<StructTag>(structTag)};
1701
1702
1
    TagSequence typeTagsSequence(typeTags);
1703
1704
    // Call the ToString method
1705
1
    std::string actual = typeTagsSequence.ToString();
1706
1707
    // Compute the expected string
1708
1
    std::ostringstream oss;
1709
1
    for (const auto& tag : typeTags) {
1710
1
        oss << tag->ToString();
1711
1
    }
1712
1
    std::string expected = oss.str();
1713
1714
    // Check that the returned string matches the expected string
1715
1
    EXPECT_EQ(expected, actual);
1716
1
}
1717
1718
1
TEST(StructTagTest, ToStringTest) {
1719
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
1720
1
    std::string module = "aptos_coin";
1721
1
    std::string name = "AptosCoin";
1722
1
    std::vector<std::shared_ptr<ISerializableTag>> typeArgs; // Fill this with actual ISerializableTag instances
1723
1724
1
    StructTag structTag(accountAddress, module, name, typeArgs);
1725
1726
    // Call the ToString method
1727
1
    std::string actual = structTag.ToString();
1728
1729
    // Compute the expected string
1730
1
    std::string expected = accountAddress.ToString() + "::" + module + "::" + name;
1731
1
    if (!typeArgs.empty()) {
1732
0
        expected += "<" + typeArgs[0]->ToString();
1733
0
        for (size_t i = 1; i < typeArgs.size(); ++i) {
1734
0
            expected += ", " + typeArgs[i]->ToString();
1735
0
        }
1736
0
        expected += ">";
1737
0
    }
1738
1739
    // Check that the returned string matches the expected string
1740
1
    EXPECT_EQ(expected, actual);
1741
1
}
1742
1743
1
TEST(StructTagTest, FromStrTest) {
1744
    // Define the typeTag string
1745
1
    std::string typeTag = "0x1::aptos_coin::AptosCoin";
1746
1747
    // Call the FromStr method
1748
1
    StructTag actual = StructTag::FromStr(typeTag);
1749
1750
    // Define the expected StructTag
1751
1
    AccountAddress expectedAddress = AccountAddress::FromHex("0x1");
1752
1
    std::string expectedModule = "aptos_coin";
1753
1
    std::string expectedName = "AptosCoin";
1754
1
    std::vector<std::shared_ptr<ISerializableTag>> expectedTypeArgs; // No type arguments in this case
1755
1
    StructTag expected(expectedAddress, expectedModule, expectedName, expectedTypeArgs);
1756
1757
    // Check that the returned StructTag matches the expected StructTag
1758
1
    EXPECT_EQ(expected, actual);
1759
1
}
1760
1761
TEST(ISerializableTag, DeserializeTagBool)
1762
1
{
1763
1
    bool actual = true;
1764
1
    Serialization s;
1765
1
    s.SerializeBool(actual);
1766
1
    std::vector<uint8_t> res;
1767
1
    std::vector<uint8_t> data = s.GetBytes();
1768
1
    res.push_back((uint8_t)TypeTag::BOOL);
1769
1
    res.insert(res.end(),data.begin(),data.end());
1770
1771
1
    Deserialization d(res);
1772
1
    std::shared_ptr<ISerializableTag> result = ISerializableTag::DeserializeTag(d);
1773
1
    ASSERT_EQ(std::dynamic_pointer_cast<Bool>(result)->Variant(),TypeTag::BOOL);
1774
1
    ASSERT_EQ(std::dynamic_pointer_cast<Bool>(result)->GetValue(), true);
1775
1
}
1776
1777
TEST(ISerializableTag, DeserializeTagU8)
1778
1
{
1779
1
    Serialization s;
1780
1
    s.SerializeU8(1);
1781
1
    std::vector<uint8_t> res;
1782
1
    std::vector<uint8_t> data = s.GetBytes();
1783
1
    res.push_back((uint8_t)TypeTag::U8);
1784
1
    res.insert(res.end(),data.begin(),data.end());
1785
1786
1
    Deserialization d(res);
1787
1
    std::shared_ptr<ISerializableTag> result = ISerializableTag::DeserializeTag(d);
1788
1
    ASSERT_EQ(std::dynamic_pointer_cast<U8>(result)->Variant(),TypeTag::U8);
1789
1
    ASSERT_EQ(std::dynamic_pointer_cast<U8>(result)->GetValue(), 1);
1790
1
}
1791
1792
TEST(ISerializableTag, DeserializeTagU16)
1793
1
{
1794
1
    std::vector<uint8_t> res;
1795
1
    std::vector<uint8_t> data = {0xF4, 0x01};
1796
1
    res.push_back((uint8_t)TypeTag::U16);
1797
1
    res.insert(res.end(),data.begin(),data.end());
1798
1799
1
    Deserialization d(res);
1800
1
    std::shared_ptr<ISerializableTag> result = ISerializableTag::DeserializeTag(d);
1801
1
    ASSERT_EQ(std::dynamic_pointer_cast<U16>(result)->Variant(),TypeTag::U16);
1802
1
    ASSERT_EQ(std::dynamic_pointer_cast<U16>(result)->GetValue(), 500);
1803
1
}
1804
1805
TEST(ISerializableTag, DeserializeTagU32)
1806
1
{
1807
1
    Serialization s;
1808
1
    s.SerializeU32(1);
1809
1
    std::vector<uint8_t> res;
1810
1
    std::vector<uint8_t> data = s.GetBytes();
1811
1
    res.push_back((uint8_t)TypeTag::U32);
1812
1
    res.insert(res.end(),data.begin(),data.end());
1813
1814
1
    Deserialization d(res);
1815
1
    std::shared_ptr<ISerializableTag> result = ISerializableTag::DeserializeTag(d);
1816
1
    ASSERT_EQ(std::dynamic_pointer_cast<U32>(result)->Variant(),TypeTag::U32);
1817
1
    ASSERT_EQ(std::dynamic_pointer_cast<U32>(result)->GetValue(), 1);
1818
1
}
1819
1820
TEST(ISerializableTag, DeserializeTagU64)
1821
1
{
1822
1
    Serialization s;
1823
1
    s.SerializeU64(1);
1824
1
    std::vector<uint8_t> res;
1825
1
    std::vector<uint8_t> data = s.GetBytes();
1826
1
    res.push_back((uint8_t)TypeTag::U64);
1827
1
    res.insert(res.end(),data.begin(),data.end());
1828
1829
1
    Deserialization d(res);
1830
1
    std::shared_ptr<ISerializableTag> result = ISerializableTag::DeserializeTag(d);
1831
1
    ASSERT_EQ(std::dynamic_pointer_cast<U64>(result)->Variant(),TypeTag::U64);
1832
1
    ASSERT_EQ(std::dynamic_pointer_cast<U64>(result)->GetValue(), 1);
1833
1
}
1834
1835
TEST(ISerializableTag, DeserializeTagU128)
1836
1
{
1837
1
    Serialization s;
1838
1
    s.SerializeU128(1);
1839
1
    std::vector<uint8_t> res;
1840
1
    std::vector<uint8_t> data = s.GetBytes();
1841
1
    res.push_back((uint8_t)TypeTag::U128);
1842
1
    res.insert(res.end(),data.begin(),data.end());
1843
1844
1
    Deserialization d(res);
1845
1
    std::shared_ptr<ISerializableTag> result = ISerializableTag::DeserializeTag(d);
1846
1
    ASSERT_EQ(std::dynamic_pointer_cast<U128>(result)->Variant(),TypeTag::U128);
1847
1
    ASSERT_EQ(std::dynamic_pointer_cast<U128>(result)->GetValue(), 1);
1848
1
}
1849
1850
TEST(ISerializableTag, DeserializeTagU256)
1851
1
{
1852
1
    Serialization s;
1853
1
    s.SerializeU256(1);
1854
1
    std::vector<uint8_t> res;
1855
1
    std::vector<uint8_t> data = s.GetBytes();
1856
1
    res.push_back((uint8_t)TypeTag::U256);
1857
1
    res.insert(res.end(),data.begin(),data.end());
1858
1859
1
    Deserialization d(res);
1860
1
    std::shared_ptr<ISerializableTag> result = ISerializableTag::DeserializeTag(d);
1861
1
    ASSERT_EQ(std::dynamic_pointer_cast<U256>(result)->Variant(),TypeTag::U256);
1862
1
    ASSERT_EQ(std::dynamic_pointer_cast<U256>(result)->GetValue(), 1);
1863
1
}
1864
1865
TEST(ISerializableTag, DeserializeTagAccountAddress)
1866
1
{
1867
1
    CryptoPP::SecByteBlock publicKeyBytes = Aptos::Utils::ByteVectorToSecBlock({
1868
1
    88, 110, 60, 141, 68, 125, 118, 121,
1869
1
    34, 46, 19, 144, 51, 227, 130, 2,
1870
1
    53, 227, 61, 165, 9, 30, 155, 11,
1871
1
    184, 241, 161, 18, 207, 12, 143, 245
1872
1
});
1873
1
    PublicKey publicKey(publicKeyBytes);
1874
1
    AccountAddress accountAddress = AccountAddress::FromKey(publicKey.KeyBytes());
1875
1
    Serialization s;
1876
1
    accountAddress.Serialize(s);
1877
1
    std::vector<uint8_t> res;
1878
1
    std::vector<uint8_t> data = s.GetBytes();
1879
1
    res.push_back((uint8_t)TypeTag::ACCOUNT_ADDRESS);
1880
1
    res.insert(res.end(),data.begin(),data.end());
1881
1882
1
    Deserialization d(res);
1883
1
    std::shared_ptr<ISerializableTag> result = ISerializableTag::DeserializeTag(d);
1884
1
    ASSERT_EQ(std::dynamic_pointer_cast<AccountAddress>(result)->Variant(),TypeTag::ACCOUNT_ADDRESS);
1885
1
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Test/test_transaction_serialization.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "gtest/gtest.h"
2
#include "../BCS/Serialization.h"
3
#include "../Accounts/AccountAddress.h"
4
#include <string>
5
6
#include <cryptopp/cryptlib.h>
7
#include <cryptopp/osrng.h>
8
#include <cryptopp/sha.h>
9
#include <cryptopp/hex.h>
10
#include <cryptopp/secblock.h>
11
#include <cryptopp/aes.h>
12
#include <cryptopp/modes.h>
13
#include "../BCS/ModuleId.h"
14
#include "../BCS/EntryFunction.h"
15
#include "../BCS/TagSequence.h"
16
#include "../BCS/U64.h"
17
#include "../BCS/Bool.h"
18
#include "../BCS/Sequence.h"
19
#include "../BCS/StructTag.h"
20
#include "../BCS/Script.h"
21
#include "../BCS/ScriptArgument.h"
22
#include "../BCS/TransactionPayload.h"
23
#include "../BCS/rawtransaction.h"
24
#include "../BCS/Authenticator.h"
25
#include "../BCS/SignedTransaction.h"
26
#include "../BCS/MultiAgentRawTransaction.h"
27
#include "../HDWallet/Utils/Utils.h"
28
#include <fstream>
29
30
using CryptoPP::byte;
31
using namespace Aptos;
32
using namespace Aptos::BCS;
33
34
19
AccountAddress testAddress() {
35
19
    return AccountAddress::FromHex("0x01");
36
19
}
37
38
39
16
ModuleId testModuleId() {
40
16
    return ModuleId(testAddress(), "my_module");
41
16
}
42
43
EntryFunction testEntryFunction(const std::vector<std::shared_ptr<ISerializableTag>>& typeTags,
44
15
                                std::vector<std::shared_ptr<ISerializable>>& args) {
45
15
    return EntryFunction::Natural(testModuleId(), "some_function", TagSequence(typeTags), Sequence(args));
46
15
}
47
48
1
TEST(AddressSerialize, serializationTest) {
49
1
    Serialization s;
50
1
    s.Serialize(testAddress());
51
1
    std::vector<byte> res = s.GetBytes();
52
1
    std::vector<byte> expected = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
53
1
    ASSERT_EQ(expected, res);
54
1
}
55
56
1
TEST(MyModuleIdTests, ModuleIdSerializeTest) {
57
1
    Serialization s;
58
1
    testModuleId().Serialize(s);
59
60
1
    const byte expectedBytes[] = {
61
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109,
62
1
        121, 95, 109, 111, 100, 117, 108, 101
63
1
    };
64
65
1
    auto res = s.GetBytes();
66
67
43
    for (int i = 0; i < sizeof(expectedBytes); ++i) {
68
42
        EXPECT_EQ(expectedBytes[i], res[i]);
69
42
    }
70
1
}
71
72
1
TEST(Transaction_Simple_Serialize, TestName) {
73
1
    Serialization s;
74
1
    std::vector<std::shared_ptr<ISerializableTag>> tags;
75
1
    std::vector<std::shared_ptr<ISerializable>> args;
76
77
1
    testEntryFunction(tags, args).Serialize(s);
78
1
    s.GetBytes();
79
1
    std::vector<uint8_t> res = s.GetBytes();
80
81
1
    std::vector<uint8_t> expected = {
82
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109,
83
1
        121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 0
84
1
    };
85
86
1
    ASSERT_EQ(expected, res);
87
1
}
88
89
90
1
TEST(Transaction_EmptyArgSequence_Serialize, TestName) {
91
1
    Serialization s;
92
1
    std::vector<std::shared_ptr<ISerializableTag>> tags;
93
1
    std::vector<std::shared_ptr<ISerializable>> args;
94
95
1
    testEntryFunction(tags, args).Serialize(s);
96
97
1
    s.GetBytes();
98
1
    std::vector<uint8_t> res = s.GetBytes();
99
100
1
    std::vector<uint8_t> expected = {
101
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109,
102
1
        121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 0
103
1
    };
104
105
1
    ASSERT_EQ(expected, res);
106
1
}
107
108
1
TEST(SequenceBStringSerializeTest, SequenceBStringSerialize) {
109
1
    Serialization s;
110
1
    Sequence sequenceEmptyBString{{std::make_shared<BString>("")}};
111
1
    sequenceEmptyBString.Serialize(s);
112
1
    std::vector<uint8_t> res = s.GetBytes();
113
1
    std::vector<uint8_t> expectedBytes1 = {1, 1, 0};
114
1
    EXPECT_EQ(res, expectedBytes1);
115
116
    // Serialize a BString with one character 'A'
117
1
    s = Serialization();
118
1
    Sequence sequenceBStringA{{std::make_shared<BString>("A")}};
119
1
    sequenceBStringA.Serialize(s);
120
1
    res = s.GetBytes();
121
1
    std::vector<uint8_t> expectedBytes2 = {1, 2, 1, 65};
122
1
    EXPECT_EQ(res, expectedBytes2);
123
124
    // Serialize a BString with two characters 'AA'
125
1
    s = Serialization();
126
1
    Sequence sequenceBStringAA{{std::make_shared<BString>("AA")}};
127
1
    sequenceBStringAA.Serialize(s);
128
1
    res = s.GetBytes();
129
1
    std::vector<uint8_t> expectedBytes3 = {1, 3, 2, 65, 65};
130
1
    EXPECT_EQ(res, expectedBytes3);
131
1
}
132
133
1
TEST(SequenceOfSequenceSerializeTest, SequenceOfSequenceSerialize) {
134
1
    Serialization s;
135
1
    Sequence innerSequence{{}};
136
1
    Sequence outerSequence{{std::make_shared<Sequence>(innerSequence)}};
137
1
    outerSequence.Serialize(s);
138
139
1
    std::vector<uint8_t> actual = s.GetBytes();
140
1
    std::vector<uint8_t> expectedBytes = {1, 1, 0};
141
1
    EXPECT_EQ(actual, expectedBytes);
142
1
}
143
144
145
1
TEST(TransactionSingleStringArgSerializeTest, TransactionSingleStringArgSerialize) {
146
1
    Serialization s;
147
1
    std::vector<std::shared_ptr<ISerializable>> args;
148
1
    args.push_back(std::make_shared<BString>("wow"));
149
1
    std::vector<std::shared_ptr<ISerializableTag>> empt;
150
151
1
    testEntryFunction({}, args).Serialize(s);
152
1
    std::vector<uint8_t> actual = s.GetBytes();
153
1
    std::vector<uint8_t> expectedBytes =  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 1, 4, 3, 119, 111, 119 };
154
155
156
1
    EXPECT_EQ(actual, expectedBytes);
157
1
}
158
159
1
TEST(TransactionSingleU64ArgSerializeTest, TransactionSingleU64ArgSerialize) {
160
1
    Serialization s;
161
1
    std::vector<std::shared_ptr<ISerializable>> args;
162
1
    args.push_back(std::make_shared<U64>(555555));
163
1
    std::vector<std::shared_ptr<ISerializableTag>> empt;
164
165
1
    testEntryFunction(empt, args).Serialize(s);
166
167
1
    std::vector<uint8_t> actual = s.GetBytes();
168
1
    std::vector<uint8_t> expectedBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 1, 8, 35, 122, 8, 0, 0, 0, 0, 0 };
169
170
1
    EXPECT_EQ(actual, expectedBytes);
171
1
}
172
173
1
TEST(TransactionWithEmptyBoolArgSequenceSerializeTest, TransactionWithEmptyBoolArgSequenceSerialize) {
174
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence;
175
1
    Serialization s;
176
1
    std::vector<std::shared_ptr<ISerializable>> args = { std::make_shared<Sequence>(boolSequence) };
177
178
1
    testEntryFunction({}, args).Serialize(s);
179
180
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
181
1
    const std::vector<uint8_t> expected = {
182
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
183
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
184
1
        9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115,
185
1
        111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0,
186
1
        1, 1, 0
187
1
    };
188
189
1
    ASSERT_EQ(expected, actualVec);
190
1
}
191
192
1
TEST(TransactionOneBoolArgSequenceSerializeTest, TransactionOneBoolArgSequenceSerialize) {
193
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence = {std::make_shared<Bool>(false)};
194
1
    Serialization s;
195
1
    std::vector<std::shared_ptr<ISerializable>> args = { std::make_shared<Sequence>(boolSequence) };
196
197
1
    testEntryFunction({}, args).Serialize(s);
198
199
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
200
1
    const std::vector<uint8_t> expected = {
201
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
203
1
        9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115,
204
1
        111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0,
205
1
        1, 2, 1, 0
206
1
    };
207
208
1
    ASSERT_EQ(expected, actualVec);}
209
210
1
TEST(TransactionTwoBoolSequenceSerializeTest, TransactionTwoBoolSequenceSerialize) {
211
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence = {std::make_shared<Bool>(false), std::make_shared<Bool>(true)};
212
1
    Serialization s;
213
1
    std::vector<std::shared_ptr<ISerializable>> args = { std::make_shared<Sequence>(boolSequence) };
214
215
1
    testEntryFunction({}, args).Serialize(s);
216
217
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
218
1
    const std::vector<uint8_t> expected = {
219
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
220
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
221
1
        9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115,
222
1
        111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0,
223
1
        1, 3, 2, 0, 1
224
1
    };
225
226
1
    ASSERT_EQ(expected, actualVec);
227
1
}
228
229
1
TEST(TransactionThreeBoolArgsSequenceSerializeTest, TransactionThreeBoolArgsSequenceSerialize) {
230
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence = {std::make_shared<Bool>(false),
231
1
                                                                std::make_shared<Bool>(true),
232
1
                                                                std::make_shared<Bool>(false)
233
1
    };
234
1
    Serialization s;
235
1
    std::vector<std::shared_ptr<ISerializable>> args = { std::make_shared<Sequence>(boolSequence) };
236
237
1
    testEntryFunction({}, args).Serialize(s);
238
239
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
240
1
    const std::vector<uint8_t> expected = {
241
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
243
1
        9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115,
244
1
        111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0,
245
1
        1, 4, 3, 0, 1, 0
246
1
    };
247
248
1
    ASSERT_EQ(expected, actualVec);
249
1
}
250
251
1
TEST(TransactionWithOneStringArgSequenceSerializeTest, TransactionWithOneStringArgSequenceSerialize) {
252
1
    Serialization s;
253
1
    std::vector<std::shared_ptr<ISerializable>> args = {std::make_shared<Sequence>(
254
1
        std::vector<std::shared_ptr<ISerializable>>{std::make_shared<BString>("A")}
255
1
        )};
256
257
1
    testEntryFunction({}, args).Serialize(s);
258
259
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
260
1
    const std::vector<uint8_t> expected = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 1, 3, 1, 1, 65 };
261
262
1
    ASSERT_EQ(expected, actualVec);
263
1
}
264
265
1
TEST(TransactionWithTwoStringArgSequenceSerializeTest, TransactionWithTwoStringArgSequenceSerialize) {
266
1
    Serialization s;
267
1
    std::vector<std::shared_ptr<ISerializable>> args = {std::make_shared<Sequence>(
268
1
        std::vector<std::shared_ptr<ISerializable>>{
269
1
            std::make_shared<BString>("A"),
270
1
            std::make_shared<BString>("B")
271
1
        })
272
1
    };
273
274
1
    testEntryFunction({}, args).Serialize(s);
275
276
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
277
1
    const std::vector<uint8_t> expected = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 1, 5, 2, 1, 65, 1, 66 };
278
279
1
    ASSERT_EQ(expected, actualVec);
280
1
}
281
282
1
TEST(TransactionThreeStringArgSequenceSerializeTest, TransactionThreeStringArgSequenceSerialize) {
283
1
    Serialization s;
284
1
    std::vector<std::shared_ptr<ISerializable>> args = {std::make_shared<Sequence>(
285
1
        std::vector<std::shared_ptr<ISerializable>>{
286
1
            std::make_shared<BString>("A"),
287
1
            std::make_shared<BString>("B"),
288
1
            std::make_shared<BString>("C")
289
1
        })
290
1
    };
291
1
    testEntryFunction({}, args).Serialize(s);
292
293
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
294
1
    const std::vector<uint8_t> expected = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 1, 7, 3, 1, 65, 1, 66, 1, 67 };
295
296
1
    ASSERT_EQ(expected, actualVec);
297
1
}
298
299
1
TEST(TransactioOneStringOneBoolArgSequenceSerializeTest, TransactioOneStringOneBoolArgSequenceSerialize) {
300
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence = {std::make_shared<Bool>(false)};
301
1
    Serialization s;
302
1
    std::vector<std::shared_ptr<ISerializable>> args = {
303
1
        std::make_shared<BString>("A"),
304
1
        std::make_shared<Sequence>(boolSequence)
305
1
    };
306
1
    testEntryFunction({}, args).Serialize(s);
307
308
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
309
1
    const std::vector<uint8_t> expected = {
310
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
312
1
        9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115,
313
1
        111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0,
314
1
        2, 2, 1, 65, 2, 1, 0
315
1
    };
316
1
    ASSERT_EQ(expected, actualVec);
317
1
}
318
319
1
TEST(TransactionOneStringOneIntOneBoolArgSequenceSerializeTest, TransactionOneStringOneIntOneBoolArgSequenceSerialize) {
320
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence = {std::make_shared<Bool>(false)};
321
1
    Serialization s;
322
1
    std::vector<std::shared_ptr<ISerializable>> args = {
323
1
        std::make_shared<BString>("A"),
324
1
        std::make_shared<U64>(1),
325
1
        std::make_shared<Sequence>(boolSequence)
326
1
    };
327
1
    testEntryFunction({}, args).Serialize(s);
328
329
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
330
1
    const std::vector<uint8_t> expected = {
331
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332
1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
333
1
        9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115,
334
1
        111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0,
335
1
        3, 2, 1, 65, 8, 1, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0
336
1
    };
337
338
1
    ASSERT_EQ(expected, actualVec);
339
1
}
340
341
1
TEST(TransactionOneStringOneIntOneAddressOneBoolArgSequenceSerializeTest, TransactionOneStringOneIntOneAddressOneBoolArgSequenceSerialize) {
342
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence = {std::make_shared<Bool>(false)};
343
1
    Serialization s;
344
1
    std::vector<std::shared_ptr<ISerializable>> args = {
345
1
        std::make_shared<BString>("A"),
346
1
        std::make_shared<U64>(1),
347
1
        std::make_shared<AccountAddress>(testAddress()),
348
1
        std::make_shared<Sequence>(boolSequence)
349
1
    };
350
1
    testEntryFunction({}, args).Serialize(s);
351
352
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
353
1
    const std::vector<uint8_t> expected = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 4, 2, 1, 65, 8, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0 };
354
355
1
    ASSERT_EQ(expected, actualVec);
356
1
}
357
358
1
TEST(TransactionOneStringOneIntOneAddressMultipleArgSequencesSerializeTest, TransactionOneStringOneIntOneAddressMultipleArgSequencesSerialize) {
359
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence1 = {std::make_shared<Bool>(false)};
360
1
    std::vector<std::shared_ptr<ISerializable>> boolSequence2 = {std::make_shared<Bool>(false), std::make_shared<Bool>(true),};
361
1
    std::vector<std::shared_ptr<ISerializable>> strSequence = {std::make_shared<BString>("A"),
362
1
                                                               std::make_shared<BString>("B"),
363
1
                                                               std::make_shared<BString>("C")};
364
365
1
    Serialization s;
366
1
    std::vector<std::shared_ptr<ISerializable>> args = {
367
1
        std::make_shared<BString>("A"),
368
1
        std::make_shared<U64>(1),
369
1
        std::make_shared<AccountAddress>(testAddress()),
370
1
        std::make_shared<Sequence>(boolSequence1),
371
1
        std::make_shared<Sequence>(boolSequence2),
372
1
        std::make_shared<Sequence>(strSequence)
373
1
    };
374
1
    testEntryFunction({}, args).Serialize(s);
375
376
1
    const std::vector<uint8_t> actualVec = s.GetBytes();
377
1
    const std::vector<uint8_t> expected = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 109, 121, 95, 109, 111, 100, 117, 108, 101, 13, 115, 111, 109, 101, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 6, 2, 1, 65, 8, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 3, 2, 0, 1, 7, 3, 1, 65, 1, 66, 1, 67 };
378
379
1
    ASSERT_EQ(expected, actualVec);
380
1
}
381
382
1
TEST(ModuleFromStringTest, ModuleFromString) {
383
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
384
1
    std::string name = "coin";
385
1
    ModuleId expectedModuleId(accountAddress, name);
386
1
    ModuleId actualModuleId = ModuleId::FromStr("0x1::coin");
387
1
    EXPECT_EQ(expectedModuleId, actualModuleId);
388
1
}
389
390
1
TEST(ModuleIdTest, ToString) {
391
    // Create a ModuleId object
392
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
393
1
    std::string name = "coin";
394
1
    ModuleId moduleId(accountAddress, name);
395
396
    // Call ToString() method
397
1
    std::string actualString = moduleId.ToString();
398
399
    // Check if the resulting string matches the expected format
400
1
    std::string expectedString = "0x1::coin";
401
1
    EXPECT_EQ(expectedString, actualString);
402
1
}
403
404
1
TEST(ModuleIdTest, GetHashCode) {
405
    // Create a ModuleId object
406
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
407
1
    std::string name = "coin";
408
1
    ModuleId moduleId(accountAddress, name);
409
410
    // Call GetHashCode() method
411
1
    size_t actualHash = moduleId.GetHashCode();
412
413
    // Check if the resulting hash is 0
414
1
    EXPECT_EQ(0, actualHash);
415
1
}
416
417
1
TEST(ModuleIdTest, EqualityOperator) {
418
    // Create two identical ModuleId objects
419
1
    AccountAddress accountAddress1 = AccountAddress::FromHex("0x1");
420
1
    std::string name1 = "coin";
421
1
    ModuleId moduleId1(accountAddress1, name1);
422
1
    ModuleId moduleId2(accountAddress1, name1);
423
424
    // Check if the two identical ModuleId objects are equal
425
1
    EXPECT_TRUE(moduleId1 == moduleId2);
426
427
    // Create two different ModuleId objects
428
1
    AccountAddress accountAddress3 = AccountAddress::FromHex("0x2");
429
1
    std::string name3 = "token";
430
1
    ModuleId moduleId3(accountAddress3, name3);
431
432
    // Check if the two different ModuleId objects are not equal
433
1
    EXPECT_FALSE(moduleId1 == moduleId3);
434
1
}
435
436
1
TEST(ModuleIdTest, Constructor) {
437
    // Create an AccountAddress object and a name string
438
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
439
1
    std::string name = "coin";
440
441
    // Create a ModuleId object using the AccountAddress object and the name string
442
1
    ModuleId moduleId(accountAddress, name);
443
444
    // Check if the ToString method of the ModuleId object returns the correct string
445
1
    std::string expectedString = "0x1::coin";
446
1
    EXPECT_EQ(expectedString, moduleId.ToString());
447
1
}
448
449
1
TEST(ModuleIdTest, Equals) {
450
    // Create two identical ModuleId objects
451
1
    AccountAddress accountAddress1 = AccountAddress::FromHex("0x1");
452
1
    std::string name1 = "coin";
453
1
    ModuleId moduleId1(accountAddress1, name1);
454
455
1
    AccountAddress accountAddress2 = AccountAddress::FromHex("0x1");
456
1
    std::string name2 = "coin";
457
1
    ModuleId moduleId2(accountAddress2, name2);
458
459
    // Check if Equals returns true for identical objects
460
1
    EXPECT_TRUE(moduleId1.Equals(moduleId2));
461
462
    // Modify one of the ModuleId objects
463
1
    AccountAddress accountAddress3 = AccountAddress::FromHex("0x2");
464
1
    ModuleId moduleId3(accountAddress3, name1);
465
466
    // Check if Equals returns false for different objects
467
1
    EXPECT_FALSE(moduleId1.Equals(moduleId3));
468
469
1
    std::string name3 = "coin2";
470
1
    ModuleId moduleId4(accountAddress1, name3);
471
472
    // Check if Equals returns false for different objects
473
1
    EXPECT_FALSE(moduleId1.Equals(moduleId4));
474
1
}
475
476
1
TEST(ModuleIdTest, FromStr) {
477
    // Test with a valid ModuleId string
478
1
    std::string validModuleIdStr = "0x1::coin";
479
1
    ModuleId validModuleId = ModuleId::FromStr(validModuleIdStr);
480
    // Test with an empty string
481
1
    std::string emptyStr = "";
482
1
    EXPECT_THROW(ModuleId::FromStr(emptyStr), std::invalid_argument);
483
484
    // Test with a string with no "::"
485
1
    std::string noSeparatorStr = "0x1coin";
486
1
    EXPECT_THROW(ModuleId::FromStr(noSeparatorStr), std::invalid_argument);
487
488
    // Test with a string with "::" at the beginning
489
1
    std::string startSeparatorStr = "::coin";
490
1
    EXPECT_THROW(ModuleId::FromStr(startSeparatorStr), std::invalid_argument);
491
492
    // Test with a string with "::" at the end
493
1
    std::string endSeparatorStr = "0x1::";
494
1
    EXPECT_THROW(ModuleId::FromStr(endSeparatorStr), std::invalid_argument);
495
1
}
496
497
1
TEST(StructTagFromStringTest, StructTagFromString) {
498
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
499
1
    std::string module = "aptos_coin";
500
1
    std::string name = "AptosCoin";
501
1
    std::vector<std::shared_ptr<ISerializableTag>> tags;
502
503
1
    StructTag expectedStructTag(accountAddress, module, name, tags);
504
1
    StructTag actualStructTag = StructTag::FromStr("0x1::aptos_coin::AptosCoin");
505
506
1
    EXPECT_EQ(expectedStructTag, actualStructTag);
507
1
}
508
509
1
TEST(TagSequenceSerializeTest, TagSequenceSerialize) {
510
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
511
1
    std::string module = "aptos_coin";
512
1
    std::string name = "AptosCoin";
513
1
    std::vector<std::shared_ptr<ISerializableTag>> tags;
514
515
1
    StructTag structTag(accountAddress, module, name, tags);
516
1
    std::vector<std::shared_ptr<ISerializableTag>> typeTags = {std::make_shared<StructTag>(structTag)};
517
518
1
    TagSequence typeTagsSequence(typeTags);
519
520
    // Serialize the TagSequence
521
1
    Serialization ser;
522
1
    typeTagsSequence.Serialize(ser);
523
1
    std::vector<uint8_t> typeTagsBytes = ser.GetBytes();
524
525
    // Deserialize the serialized data
526
1
    Deserialization deser(typeTagsBytes);
527
1
    auto actualTagSeq = std::dynamic_pointer_cast<TagSequence>(TagSequence::Deserialize(deser));
528
1
    EXPECT_EQ(typeTagsSequence, *actualTagSeq);
529
1
}
530
531
1
TEST(EntryFunctionSerializeTest, EntryFunction_PayloadForTransferCoin_Serialize) {
532
1
    TagSequence typeTags{std::vector<std::shared_ptr<ISerializableTag>>{std::make_shared<StructTag>(
533
1
        AccountAddress::FromHex("0x1"),
534
1
        "aptos_coin",
535
1
        "AptosCoin",
536
1
        std::vector<std::shared_ptr<ISerializableTag>>{}
537
1
        )}
538
1
    };
539
540
1
    std::vector<std::shared_ptr<ISerializable>> args = {
541
1
                                                           std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
542
1
        std::make_shared<U64>(1000)
543
1
    };
544
545
1
    Sequence txnArgs(args);
546
547
1
    EntryFunction payload = EntryFunction::Natural(
548
1
        ModuleId(AccountAddress::FromHex("0x1"), "coin"),
549
1
        "transfer",
550
1
        typeTags,
551
1
        txnArgs
552
1
        );
553
554
1
    Serialization s;
555
1
    payload.Serialize(s);
556
557
1
    std::vector<uint8_t> actual = s.GetBytes();
558
1
    std::vector<uint8_t> expected = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 99, 111, 105, 110, 8, 116, 114, 97, 110, 115, 102, 101, 114, 1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 97, 112, 116, 111, 115, 95, 99, 111, 105, 110, 9, 65, 112, 116, 111, 115, 67, 111, 105, 110, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 232, 3, 0, 0, 0, 0, 0, 0 };
559
560
1
    ASSERT_EQ(expected, actual);
561
1
}
562
563
1
TEST(ScriptSerializeTest, ScriptSerialize) {
564
1
    std::string path = "two_by_two_transfer.mv"; // Update with your actual script path
565
1
    std::ifstream file(path, std::ios::binary);
566
567
1
    if (!file.is_open()) {
568
0
        std::cerr << "Failed to open the file: " << path << std::endl;
569
0
        ASSERT_EQ(true, false);
570
0
        return;
571
0
    }
572
1
    std::vector<uint8_t> data;
573
1
    file.seekg(0, std::ios::end);
574
1
    size_t file_size = file.tellg();
575
1
    file.seekg(0, std::ios::beg);
576
1
    data.resize(file_size);
577
578
1
    if (file.read(reinterpret_cast<char*>(data.data()), file_size)) {
579
1
        std::cout << "File read successfully. Size: " << data.size() << " bytes." << std::endl;
580
1
    } else {
581
0
        std::cerr << "Failed to read the file." << std::endl;
582
0
        ASSERT_EQ(true, false);
583
0
        return;
584
0
    }
585
586
1
    AccountAddress caroldAddress = AccountAddress::FromHex("0x1");
587
1
    AccountAddress davidAddress = AccountAddress::FromHex("0x1");
588
1
    TagSequence typeArgs{std::vector<std::shared_ptr<ISerializableTag>>{}};
589
590
1
    auto scriptArgU64_1 = std::make_shared<ScriptArgument>(ScriptArgumentTypeTag::U64, std::make_shared<U64>(100));
591
1
    auto scriptArgU64_2 = std::make_shared<ScriptArgument>(ScriptArgumentTypeTag::U64, std::make_shared<U64>(200));
592
1
    auto scriptArgAddress_1 = std::make_shared<ScriptArgument>(ScriptArgumentTypeTag::ACCOUNT_ADDRESS, std::make_shared<AccountAddress>(caroldAddress));
593
1
    auto scriptArgAddress_2 = std::make_shared<ScriptArgument>(ScriptArgumentTypeTag::ACCOUNT_ADDRESS, std::make_shared<AccountAddress>(davidAddress));
594
1
    auto scriptArgU64_3 = std::make_shared<ScriptArgument>(ScriptArgumentTypeTag::U64, std::make_shared<U64>(50));
595
596
1
    std::vector<std::shared_ptr<ISerializable>> args = {
597
1
        scriptArgU64_1, scriptArgU64_2, scriptArgAddress_1, scriptArgAddress_2, scriptArgU64_3
598
1
    };
599
1
    Sequence scriptArgs(args);
600
601
1
    Script script(data, typeArgs, scriptArgs);
602
603
1
    Serialization ser;
604
1
    script.Serialize(ser);
605
1
    std::vector<uint8_t> actual = ser.GetBytes();
606
607
1
    std::vector<uint8_t> expected =  { 187, 2, 161, 28, 235, 11, 5, 0, 0, 0, 8, 1, 0, 4, 2, 4, 10, 3, 14, 24, 4, 38, 8, 5, 46, 67, 7, 113, 62, 8, 175, 1, 32, 6, 207, 1, 20, 0, 0, 0, 1, 1, 2, 4, 1, 0, 1, 0, 3, 8, 0, 1, 4, 3, 4, 1, 0, 1, 5, 5, 6, 1, 0, 1, 6, 7, 4, 1, 0, 1, 7, 8, 6, 1, 0, 0, 2, 1, 2, 2, 2, 3, 2, 7, 6, 12, 6, 12, 3, 3, 5, 5, 3, 3, 11, 0, 1, 8, 1, 11, 0, 1, 8, 1, 11, 0, 1, 8, 1, 1, 8, 1, 2, 6, 12, 3, 1, 11, 0, 1, 9, 0, 2, 7, 11, 0, 1, 9, 0, 11, 0, 1, 9, 0, 0, 2, 7, 11, 0, 1, 9, 0, 3, 2, 5, 11, 0, 1, 9, 0, 10, 97, 112, 116, 111, 115, 95, 99, 111, 105, 110, 4, 99, 111, 105, 110, 4, 67, 111, 105, 110, 9, 65, 112, 116, 111, 115, 67, 111, 105, 110, 8, 119, 105, 116, 104, 100, 114, 97, 119, 5, 109, 101, 114, 103, 101, 7, 101, 120, 116, 114, 97, 99, 116, 7, 100, 101, 112, 111, 115, 105, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 8, 160, 134, 1, 0, 0, 0, 0, 0, 3, 8, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 1, 26, 11, 0, 10, 2, 56, 0, 12, 7, 11, 1, 10, 3, 56, 0, 12, 8, 13, 7, 11, 8, 56, 1, 13, 7, 11, 2, 11, 3, 22, 11, 6, 23, 56, 2, 12, 9, 11, 4, 11, 7, 56, 3, 11, 5, 11, 9, 56, 3, 2, 0, 5, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 200, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 50, 0, 0, 0, 0, 0, 0, 0 };
608
609
1
    ASSERT_EQ(expected, actual);
610
611
1
    Deserialization deser(actual);
612
1
    auto actualScript = std::dynamic_pointer_cast<Script>(Script::Deserialize(deser));
613
1
    ASSERT_EQ(script, *actualScript);
614
1
}
615
616
1
TEST(ScriptTest, ToString) {
617
    // Create a ISerializable object with a known ToString value
618
1
    TagSequence typeTags
619
1
        {std::vector<std::shared_ptr<ISerializableTag>>
620
1
                         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
621
622
1
    std::vector<std::shared_ptr<ISerializable>> args = {
623
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
624
1
        std::make_shared<U64>(1000),
625
1
    };
626
1
    Sequence scriptArgs(args);
627
628
1
    std::vector<uint8_t> code;  // Filled with some arbitrary bytecode
629
630
    // Create a Script object with the known ToString value
631
1
    Script script(code, typeTags, scriptArgs);
632
633
    // Call the ToString method
634
1
    std::string returned_str = script.ToString();
635
636
    // Known value is updated to the expected string
637
1
    std::string known_value = "<0x1::aptos_coin::AptosCoin>(0x11000)";
638
639
    // Assert that the returned string is the same as the string representation of the known ToString value
640
1
    EXPECT_EQ(returned_str, known_value);
641
1
}
642
643
1
TEST(ScriptTest, EqualsMethod) {
644
    // Create two identical Script objects
645
1
    TagSequence typeTags
646
1
        {std::vector<std::shared_ptr<ISerializableTag>>
647
1
                         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
648
649
1
    std::vector<std::shared_ptr<ISerializable>> args = {
650
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
651
1
        std::make_shared<U64>(1000),
652
1
    };
653
1
    Sequence scriptArgs(args);
654
655
1
    std::vector<uint8_t> code = {1, 2, 3, 4, 5};  // Some arbitrary bytecode
656
657
    // Create two identical Script objects
658
1
    Script script1(code, typeTags, scriptArgs);
659
1
    Script script2(code, typeTags, scriptArgs);
660
661
    // Assert that the two scripts are equal
662
1
    EXPECT_TRUE(script1.Equals(script2));
663
664
    // Now alter one of the scripts
665
1
    std::vector<uint8_t> codeDifferent = {5, 4, 3, 2, 1};  // Different arbitrary bytecode
666
1
    Script script3(codeDifferent, typeTags, scriptArgs);
667
668
    // Assert that the scripts are no longer equal
669
1
    EXPECT_FALSE(script1.Equals(script3));
670
1
}
671
672
1
TEST(ScriptTest, GetHashCodeMethod) {
673
    // Create a Script object
674
1
    TagSequence typeTags
675
1
        {std::vector<std::shared_ptr<ISerializableTag>>
676
1
                         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
677
678
1
    std::vector<std::shared_ptr<ISerializable>> args = {
679
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
680
1
        std::make_shared<U64>(1000),
681
1
    };
682
1
    Sequence scriptArgs(args);
683
684
1
    std::vector<uint8_t> code = {1, 2, 3, 4, 5};  // Some arbitrary bytecode
685
686
    // Create a Script object
687
1
    Script script(code, typeTags, scriptArgs);
688
689
    // Call GetHashCode() method
690
1
    size_t actualHash = script.GetHashCode();
691
692
    // Calculate expected hash
693
1
    size_t expectedHash = 17;
694
5
    for (uint8_t byte : code) {
695
5
        expectedHash = expectedHash * 23 + static_cast<size_t>(byte);
696
5
    }
697
1
    expectedHash = expectedHash * 23 + typeTags.GetHashCode();
698
1
    expectedHash = expectedHash * 23 + scriptArgs.GetHashCode();
699
700
    // Check if the resulting hash is as expected
701
1
    EXPECT_EQ(actualHash, expectedHash);
702
1
}
703
704
705
1
TEST(TransactionPayloadSerializeTest, Transaction_PayloadForTransferCoin_Serialize) {
706
1
    TagSequence typeTags
707
1
        {std::vector<std::shared_ptr<ISerializableTag>>
708
1
                         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
709
710
1
    std::vector<std::shared_ptr<ISerializable>> args = {
711
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
712
1
        std::make_shared<U64>(1000),
713
1
    };
714
1
    Sequence txnArgs(args);
715
716
1
    ModuleId moduleId(AccountAddress::FromHex("0x1"), "coin");
717
1
    EntryFunction payload = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgs);
718
719
1
    TransactionPayload txnPayload(std::make_shared<EntryFunction>(payload));
720
721
1
    Serialization ser;
722
1
    txnPayload.Serialize(ser);
723
1
    std::vector<uint8_t> actual = ser.GetBytes();
724
1
    std::vector<uint8_t> expected ={ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 99, 111, 105, 110, 8, 116, 114, 97, 110, 115, 102, 101, 114, 1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 97, 112, 116, 111, 115, 95, 99, 111, 105, 110, 9, 65, 112, 116, 111, 115, 67, 111, 105, 110, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 232, 3, 0, 0, 0, 0, 0, 0 };
725
726
1
    ASSERT_EQ(expected, actual);
727
1
}
728
729
1
TEST(TransactionPayloadTest, ToString) {
730
    // Create a ISerializable object with a known ToString value
731
1
    TagSequence typeTags
732
1
        {std::vector<std::shared_ptr<ISerializableTag>>
733
1
                         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
734
735
1
    std::vector<std::shared_ptr<ISerializable>> args = {
736
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
737
1
        std::make_shared<U64>(1000),
738
1
    };
739
1
    Sequence txnArgs(args);
740
741
1
    ModuleId moduleId(AccountAddress::FromHex("0x1"), "coin");
742
1
    EntryFunction payload = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgs);
743
744
    // Create a TransactionPayload object with the known ToString value
745
1
    TransactionPayload transactionPayload(std::make_shared<EntryFunction>(payload));
746
747
    // Call the ToString method
748
1
    std::string returned_str = transactionPayload.ToString();
749
750
    // Known value is updated to the expected string
751
1
    std::string known_value = "0x1::coin::transfer<0x1::aptos_coin::AptosCoin>(000000000000000000000000000000012323000000)";
752
753
    // Assert that the returned string is the same as the string representation of the known ToString value
754
1
    EXPECT_EQ(returned_str, known_value);
755
1
}
756
757
1
TEST(TransactionPayloadTest, EqualsMethod) {
758
    // Create two identical TransactionPayload objects
759
1
    TagSequence typeTags
760
1
        {std::vector<std::shared_ptr<ISerializableTag>>
761
1
                         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
762
763
1
    std::vector<std::shared_ptr<ISerializable>> args = {
764
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
765
1
        std::make_shared<U64>(1000),
766
1
    };
767
1
    Sequence txnArgs(args);
768
769
1
    ModuleId moduleId(AccountAddress::FromHex("0x1"), "coin");
770
1
    EntryFunction payload = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgs);
771
772
1
    TransactionPayload payload1(std::make_shared<EntryFunction>(payload));
773
1
    TransactionPayload payload2(std::make_shared<EntryFunction>(payload));
774
775
    // Assert that the two payloads are equal
776
1
    EXPECT_TRUE(payload1.Equals(payload2));
777
778
    // Now alter one of the payloads
779
1
    ModuleId moduleIdDifferent(AccountAddress::FromHex("0x2"), "coin");
780
1
    EntryFunction payloadDifferent = EntryFunction::Natural(moduleIdDifferent, "transfer", typeTags, txnArgs);
781
1
    TransactionPayload payload3(std::make_shared<EntryFunction>(payloadDifferent));
782
783
    // Assert that the payloads are no longer equal
784
1
    EXPECT_FALSE(payload1.Equals(payload3));
785
1
}
786
787
1
TEST(TransactionPayloadTest, GetHashCodeMethod) {
788
     // Create a TransactionPayload object
789
1
    TagSequence typeTags
790
1
        {std::vector<std::shared_ptr<ISerializableTag>>
791
1
                         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
792
793
1
    std::vector<std::shared_ptr<ISerializable>> args = {
794
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
795
1
        std::make_shared<U64>(1000),
796
1
    };
797
1
    Sequence txnArgs(args);
798
799
1
    ModuleId moduleId(AccountAddress::FromHex("0x1"), "coin");
800
1
    EntryFunction entryFunction1 = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgs);
801
802
1
    TransactionPayload payload1(std::make_shared<EntryFunction>(entryFunction1));
803
804
    // Create another identical TransactionPayload object
805
1
    EntryFunction entryFunction2 = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgs);
806
1
    TransactionPayload payload2(std::make_shared<EntryFunction>(entryFunction2));
807
808
    // Given the same input, GetHashCode should output the same hash
809
1
    EXPECT_EQ(payload1.GetHashCode(), payload2.GetHashCode());
810
1
}
811
812
813
1
TEST(RawTransactionSerializeTest, RawTransaction_TransferCoin_Serialize) {
814
1
    TagSequence typeTags
815
1
        {std::vector<std::shared_ptr<ISerializableTag>>
816
1
                         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
817
818
1
    std::vector<std::shared_ptr<ISerializable>> args = {
819
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
820
1
        std::make_shared<U64>(1000),
821
1
    };
822
1
    Sequence txnArgs(args);
823
824
1
    ModuleId moduleId(AccountAddress::FromHex("0x1"), "coin");
825
1
    EntryFunction payload = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgs);
826
827
1
    TransactionPayload txnPayload(std::make_shared<EntryFunction>(payload));
828
829
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
830
831
1
    RawTransaction rawTransaction(accountAddress, 0, txnPayload, 2000, 0, 18446744073709551615UL, 4);
832
833
1
    Serialization ser;
834
1
    rawTransaction.Serialize(ser);
835
1
    std::vector<uint8_t> actual = ser.GetBytes();
836
837
1
    std::vector<uint8_t> expected = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 99, 111, 105, 110, 8, 116, 114, 97, 110, 115, 102, 101, 114, 1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 97, 112, 116, 111, 115, 95, 99, 111, 105, 110, 9, 65, 112, 116, 111, 115, 67, 111, 105, 110, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 232, 3, 0, 0, 0, 0, 0, 0, 208, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 4 };
838
839
1
    ASSERT_EQ(expected, actual);
840
1
    Deserialization deser(actual);
841
1
    auto actualRawTxn = std::dynamic_pointer_cast<RawTransaction>(RawTransaction::Deserialize(deser));
842
843
1
    ASSERT_EQ(rawTransaction, *actualRawTxn);
844
1
}
845
846
1
TEST(RawTransactionPrehashTest, RawTransaction_TransferCoin_Prehash) {
847
1
    TagSequence typeTags
848
1
        {std::vector<std::shared_ptr<ISerializableTag>>
849
1
         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
850
851
1
    std::vector<std::shared_ptr<ISerializable>> args = {
852
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
853
1
        std::make_shared<U64>(1000),
854
1
    };
855
1
    Sequence txnArgs(args);
856
857
1
    ModuleId moduleId(AccountAddress::FromHex("0x1"), "coin");
858
1
    EntryFunction payload = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgs);
859
860
1
    TransactionPayload txnPayload(std::make_shared<EntryFunction>(payload));
861
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
862
1
    RawTransaction rawTransaction(accountAddress, 0, txnPayload, 2000, 0, 18446744073709551615UL, 4);
863
1
    std::vector<uint8_t> actual = rawTransaction.Prehash();
864
1
    std::vector<uint8_t> expected = {
865
1
        181, 233, 125, 176, 127, 160, 189, 14, 85,
866
1
        152, 170, 54, 67, 169, 188, 111, 102, 147,
867
1
        189, 220, 26, 159, 236, 158, 103, 74, 70,
868
1
        30, 170, 0, 177, 147
869
1
    };
870
871
1
    ASSERT_EQ(expected, actual);
872
1
}
873
874
1
TEST(RawTransactionKeyedTest, RawTransaction_TransferCoin_Keyed) {
875
1
    TagSequence typeTags
876
1
        {std::vector<std::shared_ptr<ISerializableTag>>
877
1
         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
878
879
1
    std::vector<std::shared_ptr<ISerializable>> args = {
880
1
        std::make_shared<AccountAddress>(AccountAddress::FromHex("0x1")),
881
1
        std::make_shared<U64>(1000),
882
1
    };
883
1
    Sequence txnArgs(args);
884
885
1
    ModuleId moduleId(AccountAddress::FromHex("0x1"), "coin");
886
1
    EntryFunction payload = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgs);
887
1
    TransactionPayload txnPayload(std::make_shared<EntryFunction>(payload));
888
1
    AccountAddress accountAddress = AccountAddress::FromHex("0x1");
889
1
    RawTransaction rawTransaction(accountAddress, 0, txnPayload, 2000, 0, 18446744073709551615UL, 4);
890
1
    std::vector<uint8_t> actual = rawTransaction.Keyed();
891
1
    std::vector<uint8_t> expected = { 181, 233, 125, 176, 127, 160, 189, 14, 85, 152, 170, 54, 67, 169, 188, 111, 102, 147, 189, 220, 26, 159, 236, 158, 103, 74, 70, 30, 170, 0, 177, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 99, 111, 105, 110, 8, 116, 114, 97, 110, 115, 102, 101, 114, 1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 97, 112, 116, 111, 115, 95, 99, 111, 105, 110, 9, 65, 112, 116, 111, 115, 67, 111, 105, 110, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 232, 3, 0, 0, 0, 0, 0, 0, 208, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 4 };
892
893
894
1
    ASSERT_EQ(expected, actual);
895
1
}
896
897
1
TEST(EntryFunctionWithCorpusTest, EntryFunction_WithCorpus_Serialize) {
898
1
    std::string senderKeyInput = "9bf49a6a0755f953811fce125f2683d50429c3bb49e074147e0089a52eae155f";
899
1
    std::string receiverKeyInput = "0564f879d27ae3c02ce82834acfa8c793a629f2ca0de6919610be82f411326be";
900
1
    int sequenceNumberInput = 11;
901
1
    int gasUnitPriceInput = 1;
902
1
    int maxGasAmountInput = 2000;
903
1
    uint64_t expirationTimestampsSecsInput = 1234567890;
904
1
    int chainIdInput = 4;
905
1
    int amountInput = 5000;
906
907
    // Initialize crypto keys and addresses
908
1
    PrivateKey senderPrivateKey = PrivateKey::FromHex(senderKeyInput);
909
1
    PublicKey senderPublicKey = senderPrivateKey.GetPublicKey();
910
1
    AccountAddress senderAccountAddress = AccountAddress::FromKey(senderPublicKey);
911
912
1
    PrivateKey receiverPrivateKey = PrivateKey::FromHex(receiverKeyInput);
913
1
    PublicKey receiverPublicKey = receiverPrivateKey.GetPublicKey();
914
1
    AccountAddress receiverAccountAddress = AccountAddress::FromKey(receiverPublicKey);
915
916
    // Transaction arguments
917
1
    std::vector<std::shared_ptr<ISerializable>> txnArgs = {
918
1
                                                           std::make_shared<AccountAddress>(receiverAccountAddress),
919
1
        std::make_shared<U64>(static_cast<uint64_t>(amountInput))
920
1
    };
921
1
    Sequence txnArgsSeq(txnArgs);
922
923
1
    TagSequence typeTags
924
1
        {std::vector<std::shared_ptr<ISerializableTag>>
925
1
         {std::make_shared<StructTag>(AccountAddress::FromHex("0x1"), "aptos_coin", "AptosCoin", std::vector<std::shared_ptr<ISerializableTag>>{})}};
926
927
1
    ModuleId moduleId(AccountAddress::FromHex("0x1"), "coin");
928
1
    EntryFunction payload = EntryFunction::Natural(moduleId, "transfer", typeTags, txnArgsSeq);
929
1
    TransactionPayload txnPayload(std::make_shared<EntryFunction>(payload));
930
931
    // Define RawTransaction
932
1
    RawTransaction rawTransactionGenerated(
933
1
        senderAccountAddress,
934
1
        sequenceNumberInput,
935
1
        txnPayload,
936
1
        maxGasAmountInput,
937
1
        gasUnitPriceInput,
938
1
        expirationTimestampsSecsInput,
939
1
        chainIdInput
940
1
        );
941
942
    // Sign the RawTransaction
943
1
    Signature senderSignature = rawTransactionGenerated.Sign(senderPrivateKey);
944
1
    bool verifySenderSignature = rawTransactionGenerated.Verify(senderPublicKey, senderSignature);
945
1
    ASSERT_TRUE(verifySenderSignature);
946
947
    // Create an Authenticator
948
1
    Authenticator authenticator(std::make_shared<Ed25519Authenticator>(senderPublicKey, senderSignature));
949
950
    // Serialize the Authenticator
951
1
    Serialization ser;
952
1
    authenticator.Serialize(ser);
953
954
    // Get the serialized bytes
955
1
    std::vector<uint8_t> actual = ser.GetBytes();
956
1
    std::vector<uint8_t> expected = { 0, 32, 185, 198, 238, 22, 48, 239, 62, 113,
957
1
                                     17, 68, 166, 72, 219, 6, 187, 178, 40, 79, 114,
958
1
                                     116, 207, 190, 229, 63, 252, 238, 80, 60, 193, 164,
959
1
                                     146, 0, 64, 242, 91, 116, 236, 96, 163, 138, 30, 215,
960
1
                                     128, 253, 43, 239, 109, 219, 110, 180, 53, 110, 58,
961
1
                                     179, 146, 118, 201, 23, 108, 223, 15, 202, 226,
962
1
                                     171, 55, 215, 155, 98, 106, 187, 67, 217, 38,
963
1
                                     233, 21, 149, 182, 101, 3, 164, 163, 201, 10,
964
1
                                     203, 174, 54, 162, 141, 64, 94, 48, 143, 53,
965
1
                                     55, 175, 114, 11 };
966
967
1
    ASSERT_EQ(expected, actual);
968
969
1
    Deserialization deser(actual);
970
1
    auto authenticatorDeserialized = std::dynamic_pointer_cast<Authenticator>(Authenticator::Deserialize(deser));
971
1
    ASSERT_EQ(authenticator.GetVariant(), authenticatorDeserialized->GetVariant());
972
1
    ASSERT_EQ(authenticator, *authenticatorDeserialized);
973
1
    SignedTransaction signedTransactionGenerated(rawTransactionGenerated, authenticator);
974
1
    ASSERT_TRUE(signedTransactionGenerated.Verify());
975
1
}
976
977
1
TEST(EntryFunction_MultiAgentWithCorpusTest, EntryFunction_MultiAgentWithCorpus_Serialize) {
978
1
    std::string senderKeyInput = "9bf49a6a0755f953811fce125f2683d50429c3bb49e074147e0089a52eae155f";
979
1
    std::string receiverKeyInput = "0564f879d27ae3c02ce82834acfa8c793a629f2ca0de6919610be82f411326be";
980
981
1
    int sequenceNumberInput = 11;
982
1
    int gasUnitPriceInput = 1;
983
1
    int maxGasAmountInput = 2000;
984
1
    unsigned long long expirationTimestampsSecsInput = 1234567890;
985
1
    int chainIdInput = 4;
986
987
1
    PrivateKey senderPrivateKey = PrivateKey::FromHex(senderKeyInput);
988
1
    PublicKey senderPublicKey = senderPrivateKey.GetPublicKey();
989
1
    AccountAddress senderAccountAddress = AccountAddress::FromKey(senderPublicKey);
990
991
1
    PrivateKey receiverPrivateKey = PrivateKey::FromHex(receiverKeyInput);
992
1
    PublicKey receiverPublicKey = receiverPrivateKey.GetPublicKey();
993
1
    AccountAddress receiverAccountAddress = AccountAddress::FromKey(receiverPublicKey);
994
995
1
    std::vector<std::shared_ptr<ISerializable>> txnArgs = {
996
1
        std::make_shared<AccountAddress>(receiverAccountAddress),
997
1
        std::make_shared<BString>("collection_name"),
998
1
        std::make_shared<BString>("token_name"),
999
1
        std::make_shared<U64>(1)
1000
1
    };
1001
1
    Sequence txnArgsSeq(txnArgs);
1002
1
    TagSequence typeTags {std::vector<std::shared_ptr<ISerializableTag>>{}};
1003
1
    ModuleId moduleId(AccountAddress::FromHex("0x3"), "token");
1004
1
    EntryFunction payload = EntryFunction::Natural(moduleId, "direct_transfer_script", typeTags, txnArgsSeq);
1005
1
    TransactionPayload pl(std::make_shared<EntryFunction>(payload));
1006
1
    RawTransaction rawTxn{
1007
1
        senderAccountAddress,
1008
1
        sequenceNumberInput,
1009
1
        pl,
1010
1
        maxGasAmountInput,
1011
1
        gasUnitPriceInput,
1012
1
        expirationTimestampsSecsInput,
1013
1
        chainIdInput
1014
1
    };
1015
1
    Sequence sq{std::vector<std::shared_ptr<ISerializable>>{std::make_shared<AccountAddress>(receiverAccountAddress)}};
1016
1
    MultiAgentRawTransaction rawTransactionGenerated{
1017
1
        rawTxn,
1018
1
        sq
1019
1
    };
1020
1021
1
    std::vector<uint8_t> keyedActual = rawTransactionGenerated.Keyed();
1022
1
    std::vector<uint8_t> keyedExpected = { 94, 250, 60, 79, 2, 248, 58, 15, 75, 45, 105, 252, 149, 198, 7, 204, 2, 130, 92, 196, 231, 190, 83, 110, 240, 153, 45, 240, 80, 217, 230, 124, 0, 125, 238, 204, 177, 8, 8, 84, 244, 153, 236, 139, 76, 27, 33, 59, 130, 197, 227, 75, 146, 92, 246, 135, 95, 236, 2, 212, 183, 122, 219, 210, 214, 11, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 116, 111, 107, 101, 110, 22, 100, 105, 114, 101, 99, 116, 95, 116, 114, 97, 110, 115, 102, 101, 114, 95, 115, 99, 114, 105, 112, 116, 0, 4, 32, 45, 19, 61, 221, 40, 27, 182, 32, 85, 88, 53, 124, 198, 172, 117, 102, 24, 23, 233, 170, 234, 195, 175, 235, 195, 40, 66, 117, 156, 191, 127, 169, 16, 15, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 95, 110, 97, 109, 101, 11, 10, 116, 111, 107, 101, 110, 95, 110, 97, 109, 101, 8, 1, 0, 0, 0, 0, 0, 0, 0, 208, 7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 210, 2, 150, 73, 0, 0, 0, 0, 4, 1, 45, 19, 61, 221, 40, 27, 182, 32, 85, 88, 53, 124, 198, 172, 117, 102, 24, 23, 233, 170, 234, 195, 175, 235, 195, 40, 66, 117, 156, 191, 127, 169 };
1023
1024
1
    EXPECT_EQ(keyedExpected, keyedActual);
1025
1
    Signature senderSignature = rawTransactionGenerated.Sign(senderPrivateKey);
1026
1
    Signature receiverSignature = rawTransactionGenerated.Sign(receiverPrivateKey);
1027
1028
1
    bool verifySenderSignature = rawTransactionGenerated.Verify(senderPublicKey, senderSignature);
1029
1
    EXPECT_TRUE(verifySenderSignature);
1030
1
    bool verifyRecieverSignature = rawTransactionGenerated.Verify(receiverPublicKey, receiverSignature);
1031
1
    EXPECT_TRUE(verifyRecieverSignature);
1032
1033
1
    Authenticator ed25519AuthSender(std::make_shared<Ed25519Authenticator>(senderPublicKey, senderSignature));
1034
1035
1
    std::unique_ptr<Serialization> ser = std::make_unique<Serialization>();
1036
1
    ed25519AuthSender.Serialize(*ser);
1037
1
    std::vector<uint8_t> actualEd25519Sender = ser->GetBytes();
1038
1
    std::vector<uint8_t> expectedEd25519Sender = { 0, 32, 185, 198, 238, 22, 48, 239, 62,
1039
1
                                                  113, 17, 68, 166, 72, 219, 6, 187, 178,
1040
1
                                                  40, 79, 114, 116, 207, 190, 229, 63, 252,
1041
1
                                                  238, 80, 60, 193, 164, 146, 0, 64, 52, 62,
1042
1
                                                  123, 16, 170, 50, 60, 72, 3, 145, 165, 215, 205,
1043
1
                                                  45, 12, 247, 8, 213, 21, 41, 185, 107, 90, 43, 224,
1044
1
                                                  140, 187, 54, 94, 79, 17, 220, 194, 207, 6, 85, 118,
1045
1
                                                  108, 247, 13, 64, 133, 59, 156, 57, 91, 98, 218, 215,
1046
1
                                                  169, 245, 142, 217, 152, 128, 61, 139, 241, 144, 27,
1047
1
                                                  167, 167, 164, 1 };
1048
1
    EXPECT_EQ(expectedEd25519Sender, actualEd25519Sender);
1049
1050
    // Test ED25519 Authenticator for receiver
1051
1
    Authenticator ed25519AuthReceiver(std::make_shared<Ed25519Authenticator>(receiverPublicKey, receiverSignature));
1052
1053
1
    ser = std::make_unique<Serialization>();
1054
1
    ed25519AuthReceiver.Serialize(*ser);
1055
1
    std::vector<uint8_t> actualEd25519AuthReceiver = ser->GetBytes();
1056
1
    std::vector<uint8_t> expectedEd25519AuthReceiver = { 0, 32, 174, 243, 244, 164, 184, 236, 161,
1057
1
                                                        223, 195, 67, 54, 27, 248, 228, 54, 189, 66, 222,
1058
1
                                                        146, 89, 192, 75, 131, 20, 235, 142, 32, 84, 221,
1059
1
                                                        110, 130, 171, 64, 138, 127, 6, 228, 4, 174, 141,
1060
1
                                                        149, 53, 176, 203, 190, 175, 183, 201, 227, 78, 149,
1061
1
                                                        254, 20, 37, 228, 82, 151, 88, 21, 10, 79, 124, 231,
1062
1
                                                        166, 131, 53, 65, 72, 173, 92, 49, 62, 195, 101, 73,
1063
1
                                                        227, 251, 41, 230, 105, 217, 0, 16, 249, 116, 103,
1064
1
                                                        201, 7, 79, 240, 174, 195, 237, 135, 247, 102, 8 };
1065
1
    EXPECT_EQ(expectedEd25519AuthReceiver, actualEd25519AuthReceiver);
1066
1067
1
    std::vector<std::tuple<std::shared_ptr<AccountAddress>, std::shared_ptr<Authenticator>>> secondarySignersTup;
1068
1
    secondarySignersTup.push_back(std::tuple<std::shared_ptr<AccountAddress>, std::shared_ptr<Authenticator>>(
1069
1
        std::make_shared<AccountAddress>(receiverAccountAddress), std::make_shared<Authenticator>(ed25519AuthReceiver)));
1070
1
    MultiAgentAuthenticator multiAgentAuthenticator(ed25519AuthSender, secondarySignersTup);
1071
1
    ser = std::make_unique<Serialization>();
1072
1
    multiAgentAuthenticator.Serialize(*ser);
1073
1
    std::vector<uint8_t> actualMultiAgentAuthenticator = ser->GetBytes();
1074
1
    std::vector<uint8_t> expectedMultiAgentAuthenticator = { 0, 32, 185, 198, 238, 22, 48, 239, 62, 113, 17, 68,
1075
1
                                                            166, 72, 219, 6, 187, 178, 40, 79, 114, 116, 207, 190,
1076
1
                                                            229, 63, 252, 238, 80, 60, 193, 164, 146, 0, 64, 52,
1077
1
                                                            62, 123, 16, 170, 50, 60, 72, 3, 145, 165, 215, 205,
1078
1
                                                            45, 12, 247, 8, 213, 21, 41, 185, 107, 90, 43, 224,
1079
1
                                                            140, 187, 54, 94, 79, 17, 220, 194, 207, 6, 85, 118,
1080
1
                                                            108, 247, 13, 64, 133, 59, 156, 57, 91, 98, 218, 215,
1081
1
                                                            169, 245, 142, 217, 152, 128, 61, 139, 241, 144, 27,
1082
1
                                                            167, 167, 164, 1, 1, 45, 19, 61, 221, 40, 27, 182,
1083
1
                                                            32, 85, 88, 53, 124, 198, 172, 117, 102, 24, 23,
1084
1
                                                            233, 170, 234, 195, 175, 235, 195, 40, 66, 117,
1085
1
                                                            156, 191, 127, 169, 1, 0, 32, 174, 243, 244, 164,
1086
1
                                                            184, 236, 161, 223, 195, 67, 54, 27, 248, 228, 54,
1087
1
                                                            189, 66, 222, 146, 89, 192, 75, 131, 20, 235, 142,
1088
1
                                                            32, 84, 221, 110, 130, 171, 64, 138, 127, 6, 228,
1089
1
                                                            4, 174, 141, 149, 53, 176, 203, 190, 175, 183, 201,
1090
1
                                                            227, 78, 149, 254, 20, 37, 228, 82, 151, 88, 21, 10,
1091
1
                                                            79, 124, 231, 166, 131, 53, 65, 72, 173, 92, 49, 62,
1092
1
                                                            195, 101, 73, 227, 251, 41, 230, 105, 217, 0, 16, 249,
1093
1
                                                            116, 103, 201, 7, 79, 240, 174, 195, 237, 135, 247, 102, 8 };
1094
1
    EXPECT_EQ(actualMultiAgentAuthenticator, expectedMultiAgentAuthenticator);
1095
1096
1
    Authenticator authenticator(std::make_shared<MultiAgentAuthenticator>(multiAgentAuthenticator));
1097
1
    ser = std::make_unique<Serialization>();
1098
1
    authenticator.Serialize(*ser);
1099
1
    std::vector<uint8_t> actualAuthenticator = ser->GetBytes();
1100
1
    std::vector<uint8_t> expectedAuthenticator = { 2, 0, 32, 185, 198, 238, 22, 48, 239, 62, 113, 17, 68, 166,
1101
1
                                                  72, 219, 6, 187, 178, 40, 79, 114, 116, 207, 190, 229, 63,
1102
1
                                                  252, 238, 80, 60, 193, 164, 146, 0, 64, 52, 62, 123, 16,
1103
1
                                                  170, 50, 60, 72, 3, 145, 165, 215, 205, 45, 12, 247, 8,
1104
1
                                                  213, 21, 41, 185, 107, 90, 43, 224, 140, 187, 54, 94,
1105
1
                                                  79, 17, 220, 194, 207, 6, 85, 118, 108, 247, 13, 64,
1106
1
                                                  133, 59, 156, 57, 91, 98, 218, 215, 169, 245, 142, 217,
1107
1
                                                  152, 128, 61, 139, 241, 144, 27, 167, 167, 164, 1, 1, 45,
1108
1
                                                  19, 61, 221, 40, 27, 182, 32, 85, 88, 53, 124, 198, 172,
1109
1
                                                  117, 102, 24, 23, 233, 170, 234, 195, 175, 235, 195,
1110
1
                                                  40, 66, 117, 156, 191, 127, 169, 1, 0, 32, 174, 243,
1111
1
                                                  244, 164, 184, 236, 161, 223, 195, 67, 54, 27, 248,
1112
1
                                                  228, 54, 189, 66, 222, 146, 89, 192, 75, 131, 20, 235,
1113
1
                                                  142, 32, 84, 221, 110, 130, 171, 64, 138, 127, 6, 228,
1114
1
                                                  4, 174, 141, 149, 53, 176, 203, 190, 175, 183, 201, 227,
1115
1
                                                  78, 149, 254, 20, 37, 228, 82, 151, 88, 21, 10, 79, 124,
1116
1
                                                  231, 166, 131, 53, 65, 72, 173, 92, 49, 62, 195, 101, 73,
1117
1
                                                  227, 251, 41, 230, 105, 217, 0, 16, 249, 116, 103, 201, 7,
1118
1
                                                  79, 240, 174, 195, 237, 135, 247, 102, 8 };
1119
1
    EXPECT_EQ(actualAuthenticator, expectedAuthenticator);
1120
1121
1122
1
    Deserialization deser(actualAuthenticator);
1123
1
    auto authenticatorDeserialized = std::dynamic_pointer_cast<Authenticator>(Authenticator::Deserialize(deser));
1124
1
    EXPECT_EQ(authenticator.GetVariant(), authenticatorDeserialized->GetVariant());
1125
1
    EXPECT_EQ(authenticator, *authenticatorDeserialized);
1126
1127
1128
1
    SignedTransaction signedTransactionGenerated(rawTransactionGenerated.Inner(), authenticator);
1129
1130
1
    ser = std::make_unique<Serialization>();
1131
1
    signedTransactionGenerated.Serialize(*ser);
1132
1
    std::vector<uint8_t> signedTxnActual = ser->GetBytes();
1133
1
    std::vector<uint8_t> signedTxnExpected = { 125, 238, 204, 177, 8, 8, 84, 244, 153, 236, 139, 76, 27,
1134
1
                                              33, 59, 130, 197, 227, 75, 146, 92, 246, 135, 95, 236, 2,
1135
1
                                              212, 183, 122, 219, 210, 214, 11, 0, 0, 0, 0, 0, 0, 0, 2,
1136
1
                                              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1137
1
                                              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 116, 111, 107, 101,
1138
1
                                              110, 22, 100, 105, 114, 101, 99, 116, 95, 116, 114, 97, 110,
1139
1
                                              115, 102, 101, 114, 95, 115, 99, 114, 105, 112, 116, 0, 4, 32,
1140
1
                                              45, 19, 61, 221, 40, 27, 182, 32, 85, 88, 53, 124, 198, 172,
1141
1
                                              117, 102, 24, 23, 233, 170, 234, 195, 175, 235, 195, 40, 66,
1142
1
                                              117, 156, 191, 127, 169, 16, 15, 99, 111, 108, 108, 101, 99,
1143
1
                                              116, 105, 111, 110, 95, 110, 97, 109, 101, 11, 10, 116, 111,
1144
1
                                              107, 101, 110, 95, 110, 97, 109, 101, 8, 1, 0, 0, 0, 0, 0,
1145
1
                                              0, 0, 208, 7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 210,
1146
1
                                              2, 150, 73, 0, 0, 0, 0, 4, 2, 0, 32, 185, 198, 238, 22, 48,
1147
1
                                              239, 62, 113, 17, 68, 166, 72, 219, 6, 187, 178, 40, 79, 114,
1148
1
                                              116, 207, 190, 229, 63, 252, 238, 80, 60, 193, 164, 146, 0, 64,
1149
1
                                              52, 62, 123, 16, 170, 50, 60, 72, 3, 145, 165, 215, 205, 45, 12,
1150
1
                                              247, 8, 213, 21, 41, 185, 107, 90, 43, 224, 140, 187, 54, 94, 79,
1151
1
                                              17, 220, 194, 207, 6, 85, 118, 108, 247, 13, 64, 133, 59, 156, 57,
1152
1
                                              91, 98, 218, 215, 169, 245, 142, 217, 152, 128, 61, 139, 241, 144,
1153
1
                                              27, 167, 167, 164, 1, 1, 45, 19, 61, 221, 40, 27, 182, 32, 85, 88,
1154
1
                                              53, 124, 198, 172, 117, 102, 24, 23, 233, 170, 234, 195, 175, 235,
1155
1
                                              195, 40, 66, 117, 156, 191, 127, 169, 1, 0, 32, 174, 243, 244, 164,
1156
1
                                              184, 236, 161, 223, 195, 67, 54, 27, 248, 228, 54, 189, 66, 222, 146,
1157
1
                                              89, 192, 75, 131, 20, 235, 142, 32, 84, 221, 110, 130, 171, 64, 138,
1158
1
                                              127, 6, 228, 4, 174, 141, 149, 53, 176, 203, 190, 175, 183, 201, 227,
1159
1
                                              78, 149, 254, 20, 37, 228, 82, 151, 88, 21, 10, 79, 124, 231, 166,
1160
1
                                              131, 53, 65, 72, 173, 92, 49, 62, 195, 101, 73, 227, 251, 41, 230,
1161
1
                                              105, 217, 0, 16, 249, 116, 103, 201, 7, 79, 240, 174, 195, 237, 135,
1162
1
                                              247, 102, 8 };
1163
1
    EXPECT_EQ(signedTxnExpected, signedTxnActual);
1164
1165
1
    EXPECT_TRUE(signedTransactionGenerated.Verify());
1166
1167
1
    std::string rawTransactionInput = "7deeccb1080854f499ec8b4c1b213b82c5e34b925cf6875fec02d4b77adbd2d60b0000000000000002000000000000000000000000000000000000000000000000000000000000000305746f6b656e166469726563745f7472616e736665725f7363726970740004202d133ddd281bb6205558357cc6ac75661817e9aaeac3afebc32842759cbf7fa9100f636f6c6c656374696f6e5f6e616d650b0a746f6b656e5f6e616d65080100000000000000d0070000000000000100000000000000d20296490000000004";
1168
1
    std::string signedTransactionInput = "7deeccb1080854f499ec8b4c1b213b82c5e34b925cf6875fec02d4b77adbd2d60b0000000000000002000000000000000000000000000000000000000000000000000000000000000305746f6b656e166469726563745f7472616e736665725f7363726970740004202d133ddd281bb6205558357cc6ac75661817e9aaeac3afebc32842759cbf7fa9100f636f6c6c656374696f6e5f6e616d650b0a746f6b656e5f6e616d65080100000000000000d0070000000000000100000000000000d20296490000000004020020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a4920040343e7b10aa323c480391a5d7cd2d0cf708d51529b96b5a2be08cbb365e4f11dcc2cf0655766cf70d40853b9c395b62dad7a9f58ed998803d8bf1901ba7a7a401012d133ddd281bb6205558357cc6ac75661817e9aaeac3afebc32842759cbf7fa9010020aef3f4a4b8eca1dfc343361bf8e436bd42de9259c04b8314eb8e2054dd6e82ab408a7f06e404ae8d9535b0cbbeafb7c9e34e95fe1425e4529758150a4f7ce7a683354148ad5c313ec36549e3fb29e669d90010f97467c9074ff0aec3ed87f76608";
1169
1170
    // Produce serialized generated transactions
1171
1
    ser = std::make_unique<Serialization>();
1172
1
    ser->Serialize(rawTransactionGenerated.Inner());
1173
1
    std::string rawTransactionGeneratedBytes = Utils::HexStringFromByteArray(ser->GetBytes());
1174
1175
1
    ser = std::make_unique<Serialization>();
1176
1
    ser->Serialize(signedTransactionGenerated);
1177
1
    std::string signedTransactionGeneratedBytes = Utils::HexStringFromByteArray(ser->GetBytes());
1178
1179
    // Verify the RawTransaction
1180
1
    EXPECT_EQ(rawTransactionInput, rawTransactionGeneratedBytes);
1181
1
    Deserialization d(Utils::ByteArrayFromHexString(rawTransactionInput));
1182
1
    auto rawTransaction = std::dynamic_pointer_cast<RawTransaction>(RawTransaction::Deserialize(d));
1183
1
    EXPECT_EQ(rawTransactionGenerated.Inner(), *rawTransaction);
1184
1185
    // Verify the SignedTransaction
1186
1
    EXPECT_EQ(signedTransactionInput, signedTransactionGeneratedBytes);
1187
1
    Deserialization d2(Utils::ByteArrayFromHexString(signedTransactionInput));
1188
1189
1
    auto signedTransaction = std::dynamic_pointer_cast<SignedTransaction>(SignedTransaction::Deserialize(d2));
1190
1191
1
    EXPECT_EQ(signedTransaction->getTransaction(), *rawTransaction);
1192
1
    EXPECT_EQ(*signedTransaction, signedTransactionGenerated);
1193
1
    EXPECT_TRUE(signedTransaction->Verify());
1194
1
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Test/test_utils.cpp
Line
Count
Source
1
#include "gtest/gtest.h"
2
#include "../HDWallet/Utils/Utils.h"
3
#include <string>
4
5
using namespace Aptos;
6
class UtilsTest : public ::testing::Test {
7
protected:
8
    const std::string PrivateKeyHex = "0x64f57603b58af16907c18a866123286e1cbce89790613558dc1775abb3fc5c8c";
9
    const std::string PrivateKeyHexTrimmed = "64f57603b58af16907c18a866123286e1cbce89790613558dc1775abb3fc5c8c";
10
    const std::string InvalidPrivateKeyLengthHexOne = "0x64f57603b58af16907c18a866123286e1cbce89790613558dc1775abb3fc5c8c98ykj";
11
    const std::string InvalidPrivateKeyLengthHexTwo = "0x64f57603b58af16907c18a866123286e1cbce89790613558dc1775abb3";
12
    const std::string InvalidCharactersPrivateKeyHex = "0x64f57603b58af16907c18a8|3286e1cbce89790613558dc1775abb3fc5c8c";
13
};
14
15
1
TEST_F(UtilsTest, IsValidHexAddressTrue) {
16
1
    ASSERT_TRUE(Utils::IsValidAddress(PrivateKeyHex));
17
1
}
18
19
1
TEST_F(UtilsTest, IsValidTrimmedHexAddressTrue) {
20
1
    ASSERT_TRUE(Utils::IsValidAddress(PrivateKeyHexTrimmed));
21
1
}
22
23
1
TEST_F(UtilsTest, IsInvalidLengthHexAddress) {
24
1
    ASSERT_FALSE(Utils::IsValidAddress(InvalidPrivateKeyLengthHexOne));
25
1
}
26
27
1
TEST_F(UtilsTest, IsInvalidShorterLengthHexAddress) {
28
1
    ASSERT_FALSE(Utils::IsValidAddress(InvalidPrivateKeyLengthHexTwo));
29
1
}
30
31
1
TEST_F(UtilsTest, IsInvalidCharacterHexAddress) {
32
1
    ASSERT_FALSE(Utils::IsValidAddress(InvalidPrivateKeyLengthHexTwo));
33
1
}
34
35
1
TEST_F(UtilsTest, Trim_RemovesCharactersFromBothEnds) {
36
    // Test trimming spaces
37
1
    std::string original = "   hello world   ";
38
1
    std::string trimmed = Utils::trim(original, " ");
39
1
    ASSERT_EQ(trimmed, "hello world");
40
41
    // Test trimming specific characters
42
1
    original = "xxxyyyzzz";
43
1
    trimmed = Utils::trim(original, "xyz");
44
1
    ASSERT_EQ(trimmed, "");
45
46
    // Test trimming when no characters should be trimmed
47
1
    original = "hello world";
48
1
    trimmed = Utils::trim(original, "xyz");
49
1
    ASSERT_EQ(trimmed, "hello world");
50
51
    // Test trimming empty string
52
1
    original = "";
53
1
    trimmed = Utils::trim(original, " ");
54
1
    ASSERT_EQ(trimmed, "");
55
56
    // Test trimming spaces and special characters
57
1
    original = " $% hello world %$ ";
58
1
    trimmed = Utils::trim(original, " $%");
59
1
    ASSERT_EQ(trimmed, "hello world");
60
1
}
61
62
1
TEST_F(UtilsTest, RTrim_RemovesCharactersFromRightEnd) {
63
    // Test trimming spaces
64
1
    std::string original = "   hello world   ";
65
1
    std::string trimmed = Utils::rtrim(original, " ");
66
1
    ASSERT_EQ(trimmed, "   hello world");
67
68
    // Test trimming specific characters
69
1
    original = "xxxyyyzzz";
70
1
    trimmed = Utils::rtrim(original, "xyz");
71
1
    ASSERT_EQ(trimmed, "");
72
73
    // Test trimming when no characters should be trimmed
74
1
    original = "hello world";
75
1
    trimmed = Utils::rtrim(original, "xyz");
76
1
    ASSERT_EQ(trimmed, "hello world");
77
78
    // Test trimming empty string
79
1
    original = "";
80
1
    trimmed = Utils::rtrim(original, " ");
81
1
    ASSERT_EQ(trimmed, "");
82
83
    // Test trimming spaces and special characters
84
1
    original = " $% hello world %$ ";
85
1
    trimmed = Utils::rtrim(original, " $%");
86
1
    ASSERT_EQ(trimmed, " $% hello world");
87
1
}
/Users/anhnph/Downloads/Work/Products/Aptos-Cpp-SDK/Test/test_wallet.cpp
Line
Count
Source
1
2
#include <gtest/gtest.h>
3
#include "../Accounts/Account.h"
4
5
#include "../HDWallet/wallet.h"
6
#include "../Accounts/Signature.h"
7
#include "../HDWallet/Utils/Utils.h"
8
9
using namespace Aptos;
10
using namespace Aptos::HDWallet;
11
static const std::string mnemo = "stadium valid laundry unknown tuition train december camera fiber vault sniff ripple";
12
static const std::string Message = "WELCOME TO APTOS!";
13
14
static const std::vector<uint8_t> SeedNoPhrase = {
15
    125, 168, 253, 127, 208, 60, 18, 9,
16
    188, 118, 79, 248, 22, 177, 237, 218,
17
    150, 207, 109, 18, 216, 194, 161, 200,
18
    81, 195, 154, 226, 124, 148, 120, 121,
19
    218, 142, 242, 104, 202, 44, 246, 159,
20
    208, 250, 42, 58, 204, 203, 89, 114,
21
    96, 203, 231, 176, 7, 227, 4, 176,
22
    222, 227, 185, 220, 247, 250, 223, 167 };
23
24
static const std::vector<uint8_t> MessageUt8Bytes = {
25
    87, 69, 76, 67, 79, 77, 69, 32,
26
    84, 79, 32, 65, 80, 84, 79, 83, 33 };
27
28
static const std::vector<uint8_t> SignatureBytes = {
29
    170, 66, 187, 194, 169, 252, 117, 27,
30
    238, 238, 59, 49, 43, 132, 82, 196,
31
    69, 199, 212, 171, 134, 152, 3, 107,
32
    12, 249, 242, 228, 106, 9, 139, 176,
33
    44, 54, 159, 188, 141, 254, 253, 35,
34
    26, 18, 141, 138, 75, 185, 173, 207,
35
    228, 94, 7, 24, 139, 117, 140, 58,
36
    211, 152, 215, 248, 78, 130, 239, 5 };
37
38
1
TEST(WalletTest, CreateWallet) {
39
1
    Wallet wallet = Wallet(mnemo);
40
1
    ASSERT_EQ(SeedNoPhrase, wallet.DeriveMnemonicSeed());
41
1
}
42
43
1
TEST(WalletTest, SignMessage) {
44
1
    Signature signatureObject = Signature(Utils::ByteVectorToSecBlock(SignatureBytes));
45
1
    Wallet wallet = Wallet(mnemo);
46
1
    Account acct = wallet.account();
47
1
    Signature signature = acct.Sign(Utils::ByteVectorToSecBlock(MessageUt8Bytes));
48
1
    EXPECT_EQ(signatureObject, signature);
49
1
}
50
51
1
TEST(WalletTest, VerifySignature) {
52
1
    Signature signatureObject = Signature(Utils::ByteVectorToSecBlock(SignatureBytes));
53
1
    Wallet wallet = Wallet(mnemo);
54
1
    Account acct = wallet.account();
55
1
    bool verify = acct.Verify(Utils::ByteVectorToSecBlock(MessageUt8Bytes), signatureObject);
56
1
    EXPECT_TRUE(verify);
57
1
}
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/classification.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library classification.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_CLASSIFICATION_HPP
12
#define BOOST_STRING_CLASSIFICATION_HPP
13
14
#include <algorithm>
15
#include <locale>
16
#include <boost/range/value_type.hpp>
17
#include <boost/range/as_literal.hpp>
18
#include <boost/algorithm/string/detail/classification.hpp>
19
#include <boost/algorithm/string/predicate_facade.hpp>
20
21
22
/*! \file
23
    Classification predicates are included in the library to give 
24
    some more convenience when using algorithms like \c trim() and \c all(). 
25
    They wrap functionality of STL classification functions ( e.g. \c std::isspace() )
26
    into generic functors. 
27
*/
28
29
namespace boost {
30
    namespace algorithm {
31
32
//  classification functor generator -------------------------------------//
33
34
        //! is_classified predicate
35
        /*!
36
            Construct the \c is_classified predicate. This predicate holds if the input is
37
            of specified \c std::ctype category.
38
39
            \param Type A \c std::ctype category
40
            \param Loc A locale used for classification
41
            \return An instance of the \c is_classified predicate 
42
        */
43
        inline detail::is_classifiedF
44
        is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale())
45
0
        {
46
0
            return detail::is_classifiedF(Type, Loc);
47
0
        }
48
49
        //! is_space predicate
50
        /*!
51
            Construct the \c is_classified predicate for the \c ctype_base::space category.   
52
53
            \param Loc A locale used for classification
54
            \return An instance of the \c is_classified predicate
55
        */
56
        inline detail::is_classifiedF 
57
        is_space(const std::locale& Loc=std::locale())
58
0
        {
59
0
            return detail::is_classifiedF(std::ctype_base::space, Loc);
60
0
        }
61
62
        //! is_alnum predicate
63
        /*!
64
            Construct the \c is_classified predicate for the \c ctype_base::alnum category.   
65
66
            \param Loc A locale used for classification
67
            \return An instance of the \c is_classified predicate 
68
        */
69
        inline detail::is_classifiedF 
70
        is_alnum(const std::locale& Loc=std::locale())
71
0
        {
72
0
            return detail::is_classifiedF(std::ctype_base::alnum, Loc);
73
0
        }
74
75
        //! is_alpha predicate
76
        /*!
77
            Construct the \c is_classified predicate for the \c ctype_base::alpha category.   
78
79
            \param Loc A locale used for classification
80
            \return An instance of the \c is_classified predicate 
81
        */
82
        inline detail::is_classifiedF 
83
        is_alpha(const std::locale& Loc=std::locale())
84
0
        {
85
0
            return detail::is_classifiedF(std::ctype_base::alpha, Loc);
86
0
        }
87
88
        //! is_cntrl predicate
89
        /*!
90
            Construct the \c is_classified predicate for the \c ctype_base::cntrl category.   
91
92
            \param Loc A locale used for classification
93
            \return An instance of the \c is_classified predicate 
94
        */
95
        inline detail::is_classifiedF 
96
        is_cntrl(const std::locale& Loc=std::locale())
97
0
        {
98
0
            return detail::is_classifiedF(std::ctype_base::cntrl, Loc);
99
0
        }
100
101
        //! is_digit predicate
102
        /*!
103
            Construct the \c is_classified predicate for the \c ctype_base::digit category.   
104
105
            \param Loc A locale used for classification
106
            \return An instance of the \c is_classified predicate 
107
        */
108
        inline detail::is_classifiedF 
109
        is_digit(const std::locale& Loc=std::locale())
110
15
        {
111
15
            return detail::is_classifiedF(std::ctype_base::digit, Loc);
112
15
        }
113
114
        //! is_graph predicate
115
        /*!
116
            Construct the \c is_classified predicate for the \c ctype_base::graph category.   
117
118
            \param Loc A locale used for classification
119
            \return An instance of the \c is_classified predicate 
120
        */
121
        inline detail::is_classifiedF
122
        is_graph(const std::locale& Loc=std::locale())
123
0
        {
124
0
            return detail::is_classifiedF(std::ctype_base::graph, Loc);
125
0
        }
126
127
        //! is_lower predicate
128
        /*!
129
            Construct the \c is_classified predicate for the \c ctype_base::lower category.   
130
131
            \param Loc A locale used for classification
132
            \return An instance of \c is_classified predicate 
133
        */
134
        inline detail::is_classifiedF 
135
        is_lower(const std::locale& Loc=std::locale())
136
0
        {
137
0
            return detail::is_classifiedF(std::ctype_base::lower, Loc);
138
0
        }
139
140
        //! is_print predicate
141
        /*!
142
            Construct the \c is_classified predicate for the \c ctype_base::print category.   
143
144
            \param Loc A locale used for classification
145
            \return An instance of the \c is_classified predicate 
146
        */
147
        inline detail::is_classifiedF 
148
        is_print(const std::locale& Loc=std::locale())
149
0
        {
150
0
            return detail::is_classifiedF(std::ctype_base::print, Loc);
151
0
        }
152
153
        //! is_punct predicate
154
        /*!
155
            Construct the \c is_classified predicate for the \c ctype_base::punct category.   
156
157
            \param Loc A locale used for classification
158
            \return An instance of the \c is_classified predicate 
159
        */
160
        inline detail::is_classifiedF 
161
        is_punct(const std::locale& Loc=std::locale())
162
0
        {
163
0
            return detail::is_classifiedF(std::ctype_base::punct, Loc);
164
0
        }
165
166
        //! is_upper predicate
167
        /*!
168
            Construct the \c is_classified predicate for the \c ctype_base::upper category.   
169
170
            \param Loc A locale used for classification
171
            \return An instance of the \c is_classified predicate 
172
        */
173
        inline detail::is_classifiedF 
174
        is_upper(const std::locale& Loc=std::locale())
175
0
        {
176
0
            return detail::is_classifiedF(std::ctype_base::upper, Loc);
177
0
        }
178
179
        //! is_xdigit predicate
180
        /*!
181
            Construct the \c is_classified predicate for the \c ctype_base::xdigit category.  
182
183
            \param Loc A locale used for classification
184
            \return An instance of the \c is_classified predicate 
185
        */
186
        inline detail::is_classifiedF 
187
        is_xdigit(const std::locale& Loc=std::locale())
188
0
        {
189
0
            return detail::is_classifiedF(std::ctype_base::xdigit, Loc);
190
0
        }
191
192
        //! is_any_of predicate
193
        /*!
194
            Construct the \c is_any_of predicate. The predicate holds if the input
195
            is included in the specified set of characters.
196
197
            \param Set A set of characters to be recognized
198
            \return An instance of the \c is_any_of predicate 
199
        */
200
        template<typename RangeT>
201
        inline detail::is_any_ofF<
202
            BOOST_STRING_TYPENAME range_value<RangeT>::type> 
203
        is_any_of( const RangeT& Set )
204
3
        {
205
3
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_set(boost::as_literal(Set));
206
3
            return detail::is_any_ofF<BOOST_STRING_TYPENAME range_value<RangeT>::type>(lit_set); 
207
3
        }
208
209
        //! is_from_range predicate
210
        /*!
211
            Construct the \c is_from_range predicate. The predicate holds if the input
212
            is included in the specified range. (i.e. From <= Ch <= To )
213
214
            \param From The start of the range
215
            \param To The end of the range
216
            \return An instance of the \c is_from_range predicate 
217
        */
218
        template<typename CharT>
219
        inline detail::is_from_rangeF<CharT> is_from_range(CharT From, CharT To)
220
        {
221
            return detail::is_from_rangeF<CharT>(From,To); 
222
        }
223
        
224
        // predicate combinators ---------------------------------------------------//
225
226
        //! predicate 'and' composition predicate
227
        /*!
228
            Construct the \c class_and predicate. This predicate can be used
229
            to logically combine two classification predicates. \c class_and holds,
230
            if both predicates return true.
231
232
            \param Pred1 The first predicate
233
            \param Pred2 The second predicate
234
            \return An instance of the \c class_and predicate     
235
        */
236
        template<typename Pred1T, typename Pred2T>
237
        inline detail::pred_andF<Pred1T, Pred2T>
238
        operator&&( 
239
            const predicate_facade<Pred1T>& Pred1, 
240
            const predicate_facade<Pred2T>& Pred2 )
241
        {    
242
            // Doing the static_cast with the pointer instead of the reference
243
            // is a workaround for some compilers which have problems with
244
            // static_cast's of template references, i.e. CW8. /grafik/
245
            return detail::pred_andF<Pred1T,Pred2T>(
246
                *static_cast<const Pred1T*>(&Pred1), 
247
                *static_cast<const Pred2T*>(&Pred2) );
248
        }
249
250
        //! predicate 'or' composition predicate
251
        /*!
252
            Construct the \c class_or predicate. This predicate can be used
253
            to logically combine two classification predicates. \c class_or holds,
254
            if one of the predicates return true.
255
256
            \param Pred1 The first predicate
257
            \param Pred2 The second predicate
258
            \return An instance of the \c class_or predicate     
259
        */
260
        template<typename Pred1T, typename Pred2T>
261
        inline detail::pred_orF<Pred1T, Pred2T>
262
        operator||( 
263
            const predicate_facade<Pred1T>& Pred1, 
264
            const predicate_facade<Pred2T>& Pred2 )
265
        {    
266
            // Doing the static_cast with the pointer instead of the reference
267
            // is a workaround for some compilers which have problems with
268
            // static_cast's of template references, i.e. CW8. /grafik/
269
            return detail::pred_orF<Pred1T,Pred2T>(
270
                *static_cast<const Pred1T*>(&Pred1), 
271
                *static_cast<const Pred2T*>(&Pred2));
272
        }
273
274
        //! predicate negation operator
275
        /*!
276
            Construct the \c class_not predicate. This predicate represents a negation. 
277
            \c class_or holds if of the predicates return false.
278
279
            \param Pred The predicate to be negated
280
            \return An instance of the \c class_not predicate     
281
        */
282
        template<typename PredT>
283
        inline detail::pred_notF<PredT>
284
        operator!( const predicate_facade<PredT>& Pred )
285
        {
286
            // Doing the static_cast with the pointer instead of the reference
287
            // is a workaround for some compilers which have problems with
288
            // static_cast's of template references, i.e. CW8. /grafik/
289
            return detail::pred_notF<PredT>(*static_cast<const PredT*>(&Pred)); 
290
        }
291
292
    } // namespace algorithm
293
294
    // pull names to the boost namespace
295
    using algorithm::is_classified;
296
    using algorithm::is_space;
297
    using algorithm::is_alnum;
298
    using algorithm::is_alpha;
299
    using algorithm::is_cntrl;
300
    using algorithm::is_digit;
301
    using algorithm::is_graph;
302
    using algorithm::is_lower;
303
    using algorithm::is_upper;
304
    using algorithm::is_print;
305
    using algorithm::is_punct;
306
    using algorithm::is_xdigit;
307
    using algorithm::is_any_of;
308
    using algorithm::is_from_range;
309
310
} // namespace boost
311
312
#endif  // BOOST_STRING_PREDICATE_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/compare.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library compare.hpp header file  -------------------------//
2
3
//  Copyright Pavol Droba 2002-2006.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_COMPARE_HPP
12
#define BOOST_STRING_COMPARE_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <locale>
16
17
/*! \file
18
    Defines element comparison predicates. Many algorithms in this library can
19
    take an additional argument with a predicate used to compare elements.
20
    This makes it possible, for instance, to have case insensitive versions
21
    of the algorithms.
22
*/
23
24
namespace boost {
25
    namespace algorithm {
26
27
        //  is_equal functor  -----------------------------------------------//
28
29
        //! is_equal functor
30
        /*!
31
            Standard STL equal_to only handle comparison between arguments
32
            of the same type. This is a less restrictive version which wraps operator ==.
33
        */
34
        struct is_equal
35
        {
36
            //! Function operator
37
            /*!
38
                Compare two operands for equality
39
            */
40
            template< typename T1, typename T2 >
41
                bool operator()( const T1& Arg1, const T2& Arg2 ) const
42
39
            {
43
39
                return Arg1==Arg2;
44
39
            }
45
        };
46
47
        //! case insensitive version of is_equal
48
        /*!
49
            Case insensitive comparison predicate. Comparison is done using
50
            specified locales.
51
        */
52
        struct is_iequal
53
        {
54
            //! Constructor
55
            /*!
56
                \param Loc locales used for comparison
57
            */
58
            is_iequal( const std::locale& Loc=std::locale() ) :
59
0
                m_Loc( Loc ) {}
60
61
            //! Function operator
62
            /*!
63
                Compare two operands. Case is ignored.
64
            */
65
            template< typename T1, typename T2 >
66
                bool operator()( const T1& Arg1, const T2& Arg2 ) const
67
            {
68
                #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x564) && !defined(_USE_OLD_RW_STL)
69
                    return std::toupper(Arg1)==std::toupper(Arg2);
70
                #else
71
                    return std::toupper<T1>(Arg1,m_Loc)==std::toupper<T2>(Arg2,m_Loc);
72
                #endif
73
            }
74
75
        private:
76
            std::locale m_Loc;
77
        };
78
79
        //  is_less functor  -----------------------------------------------//
80
81
        //! is_less functor
82
        /*!
83
            Convenient version of standard std::less. Operation is templated, therefore it is 
84
            not required to specify the exact types upon the construction
85
         */
86
        struct is_less
87
        {
88
            //! Functor operation
89
            /*!
90
                Compare two operands using > operator
91
             */
92
            template< typename T1, typename T2 >
93
                bool operator()( const T1& Arg1, const T2& Arg2 ) const
94
            {
95
                return Arg1<Arg2;
96
            }
97
        };
98
99
100
        //! case insensitive version of is_less
101
        /*!
102
            Case insensitive comparison predicate. Comparison is done using
103
            specified locales.
104
        */
105
        struct is_iless
106
        {
107
            //! Constructor
108
            /*!
109
                \param Loc locales used for comparison
110
            */
111
            is_iless( const std::locale& Loc=std::locale() ) :
112
0
                m_Loc( Loc ) {}
113
114
            //! Function operator
115
            /*!
116
                Compare two operands. Case is ignored.
117
            */
118
            template< typename T1, typename T2 >
119
                bool operator()( const T1& Arg1, const T2& Arg2 ) const
120
            {
121
                #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x564) && !defined(_USE_OLD_RW_STL)
122
                    return std::toupper(Arg1)<std::toupper(Arg2);
123
                #else
124
                    return std::toupper<T1>(Arg1,m_Loc)<std::toupper<T2>(Arg2,m_Loc);
125
                #endif
126
            }
127
128
        private:
129
            std::locale m_Loc;
130
        };
131
132
        //  is_not_greater functor  -----------------------------------------------//
133
134
        //! is_not_greater functor
135
        /*!
136
            Convenient version of standard std::not_greater_to. Operation is templated, therefore it is 
137
            not required to specify the exact types upon the construction
138
         */
139
        struct is_not_greater
140
        {
141
            //! Functor operation
142
            /*!
143
                Compare two operands using > operator
144
             */
145
            template< typename T1, typename T2 >
146
                bool operator()( const T1& Arg1, const T2& Arg2 ) const
147
            {
148
                return Arg1<=Arg2;
149
            }
150
        };
151
152
153
        //! case insensitive version of is_not_greater
154
        /*!
155
            Case insensitive comparison predicate. Comparison is done using
156
            specified locales.
157
        */
158
        struct is_not_igreater
159
        {
160
            //! Constructor
161
            /*!
162
                \param Loc locales used for comparison
163
            */
164
            is_not_igreater( const std::locale& Loc=std::locale() ) :
165
0
                m_Loc( Loc ) {}
166
167
            //! Function operator
168
            /*!
169
                Compare two operands. Case is ignored.
170
            */
171
            template< typename T1, typename T2 >
172
                bool operator()( const T1& Arg1, const T2& Arg2 ) const
173
            {
174
                #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x564) && !defined(_USE_OLD_RW_STL)
175
                    return std::toupper(Arg1)<=std::toupper(Arg2);
176
                #else
177
                    return std::toupper<T1>(Arg1,m_Loc)<=std::toupper<T2>(Arg2,m_Loc);
178
                #endif
179
            }
180
181
        private:
182
            std::locale m_Loc;
183
        };
184
185
186
    } // namespace algorithm
187
188
    // pull names to the boost namespace
189
    using algorithm::is_equal;
190
    using algorithm::is_iequal;
191
    using algorithm::is_less;
192
    using algorithm::is_iless;
193
    using algorithm::is_not_greater;
194
    using algorithm::is_not_igreater;
195
196
} // namespace boost
197
198
199
#endif  // BOOST_STRING_COMPARE_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/concept.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library concept.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_CONCEPT_HPP
12
#define BOOST_STRING_CONCEPT_HPP
13
14
#include <boost/concept_check.hpp>
15
#include <boost/range/iterator_range_core.hpp>
16
#include <boost/range/begin.hpp>
17
#include <boost/range/end.hpp>
18
19
/*! \file 
20
    Defines concepts used in string_algo library
21
*/
22
23
namespace boost {
24
    namespace algorithm {
25
26
        //! Finder concept
27
        /*!
28
            Defines the Finder concept. Finder is a functor which selects
29
            an arbitrary part of a string. Search is performed on
30
            the range specified by starting and ending iterators.
31
32
            Result of the find operation must be convertible to iterator_range.
33
        */
34
        template<typename FinderT, typename IteratorT>
35
        struct FinderConcept
36
        {
37
        private:
38
            typedef iterator_range<IteratorT> range;
39
        public:
40
            void constraints()
41
0
            {
42
0
                // Operation
43
0
                r=(*pF)(i,i);
44
0
            }
Unexecuted instantiation: _ZN5boost9algorithm13FinderConceptINS0_6detail13token_finderFINS2_10is_any_ofFIcEEEENSt3__111__wrap_iterIPKcEEE11constraintsEv
Unexecuted instantiation: _ZN5boost9algorithm13FinderConceptINS0_6detail13first_finderFIPKcNS0_8is_equalEEENSt3__111__wrap_iterIS5_EEE11constraintsEv
45
        private:
46
            range r;
47
            IteratorT i;
48
            FinderT* pF;    
49
        }; // Finder_concept
50
51
        
52
        //! Formatter concept
53
        /*!
54
            Defines the Formatter concept. Formatter is a functor, which
55
            takes a result from a finder operation and transforms it
56
            in a specific way.
57
58
            Result must be a container supported by container_traits, 
59
            or a reference to it.
60
        */
61
        template<typename FormatterT, typename FinderT, typename IteratorT>
62
        struct FormatterConcept
63
        {
64
        public:
65
            void constraints()
66
0
            {
67
0
                // Operation
68
0
                ::boost::begin((*pFo)( (*pF)(i,i) ));
69
0
                ::boost::end((*pFo)( (*pF)(i,i) ));
70
0
            }
71
        private:
72
            IteratorT i;
73
            FinderT* pF;
74
            FormatterT *pFo;
75
        }; // FormatterConcept;
76
77
    } // namespace algorithm
78
} // namespace boost
79
80
81
82
83
#endif  // BOOST_STRING_CONCEPT_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/classification.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library classification.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
// 
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP
12
#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <algorithm>
16
#include <cstring>
17
#include <functional>
18
#include <locale>
19
20
#include <boost/range/begin.hpp>
21
#include <boost/range/distance.hpp>
22
#include <boost/range/end.hpp>
23
24
#include <boost/algorithm/string/predicate_facade.hpp>
25
#include <boost/type_traits/remove_const.hpp>
26
27
namespace boost {
28
    namespace algorithm {
29
        namespace detail {
30
31
//  classification functors -----------------------------------------------//
32
33
   // is_classified functor
34
            struct is_classifiedF :
35
                public predicate_facade<is_classifiedF>
36
            {
37
                // Boost.ResultOf support
38
                typedef bool result_type;
39
40
                // Constructor from a locale
41
                is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) :
42
15
                    m_Type(Type), m_Locale(Loc) {}
43
                // Operation
44
                template<typename CharT>
45
                bool operator()( CharT Ch ) const
46
24
                {
47
24
                    return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
48
24
                }
49
50
                #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x582) && !defined(_USE_OLD_RW_STL)
51
                    template<>
52
                    bool operator()( char const Ch ) const
53
                    {
54
                        return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch );
55
                    }
56
                #endif
57
58
            private:
59
                std::ctype_base::mask m_Type;
60
                std::locale m_Locale;
61
            };
62
63
64
            // is_any_of functor
65
            /*
66
                returns true if the value is from the specified set
67
            */
68
            template<typename CharT>
69
            struct is_any_ofF :
70
                public predicate_facade<is_any_ofF<CharT> >
71
            {
72
            private:
73
                // set cannot operate on const value-type
74
                typedef typename ::boost::remove_const<CharT>::type set_value_type;
75
76
            public:     
77
                // Boost.ResultOf support
78
                typedef bool result_type;
79
80
                // Constructor
81
                template<typename RangeT>
82
                is_any_ofF( const RangeT& Range ) : m_Size(0)
83
3
                {
84
                    // Prepare storage
85
3
                    m_Storage.m_dynSet=0;
86
87
3
                    std::size_t Size=::boost::distance(Range);
88
3
                    m_Size=Size;
89
3
                    set_value_type* Storage=0;
90
91
3
                    if(use_fixed_storage(m_Size))
92
3
                    {
93
                        // Use fixed storage
94
3
                        Storage=&m_Storage.m_fixSet[0];
95
3
                    }
96
0
                    else
97
0
                    {
98
                        // Use dynamic storage
99
0
                        m_Storage.m_dynSet=new set_value_type[m_Size];
100
0
                        Storage=m_Storage.m_dynSet;
101
0
                    }
102
103
                    // Use fixed storage
104
3
                    ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
105
3
                    ::std::sort(Storage, Storage+m_Size);
106
3
                }
107
108
                // Copy constructor
109
                is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size)
110
138
                {
111
                    // Prepare storage
112
138
                    m_Storage.m_dynSet=0;               
113
138
                    const set_value_type* SrcStorage=0;
114
138
                    set_value_type* DestStorage=0;
115
116
138
                    if(use_fixed_storage(m_Size))
117
138
                    {
118
                        // Use fixed storage
119
138
                        DestStorage=&m_Storage.m_fixSet[0];
120
138
                        SrcStorage=&Other.m_Storage.m_fixSet[0];
121
138
                    }
122
0
                    else
123
0
                    {
124
                        // Use dynamic storage
125
0
                        m_Storage.m_dynSet=new set_value_type[m_Size];
126
0
                        DestStorage=m_Storage.m_dynSet;
127
0
                        SrcStorage=Other.m_Storage.m_dynSet;
128
0
                    }
129
130
                    // Use fixed storage
131
138
                    ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
132
138
                }
133
134
                // Destructor
135
                ~is_any_ofF()
136
141
                {
137
141
                    if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
138
0
                    {
139
0
                        delete [] m_Storage.m_dynSet;
140
0
                    }
141
141
                }
142
143
                // Assignment
144
                is_any_ofF& operator=(const is_any_ofF& Other)
145
                {
146
                    // Handle self assignment
147
                    if(this==&Other) return *this;
148
149
                    // Prepare storage             
150
                    const set_value_type* SrcStorage;
151
                    set_value_type* DestStorage;
152
153
                    if(use_fixed_storage(Other.m_Size))
154
                    {
155
                        // Use fixed storage
156
                        DestStorage=&m_Storage.m_fixSet[0];
157
                        SrcStorage=&Other.m_Storage.m_fixSet[0];
158
159
                        // Delete old storage if was present
160
                        if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
161
                        {
162
                            delete [] m_Storage.m_dynSet;
163
                        }
164
165
                        // Set new size
166
                        m_Size=Other.m_Size;
167
                    }
168
                    else
169
                    {
170
                        // Other uses dynamic storage
171
                        SrcStorage=Other.m_Storage.m_dynSet;
172
173
                        // Check what kind of storage are we using right now
174
                        if(use_fixed_storage(m_Size))
175
                        {
176
                            // Using fixed storage, allocate new
177
                            set_value_type* pTemp=new set_value_type[Other.m_Size];
178
                            DestStorage=pTemp;
179
                            m_Storage.m_dynSet=pTemp;
180
                            m_Size=Other.m_Size;
181
                        }
182
                        else
183
                        {
184
                            // Using dynamic storage, check if can reuse
185
                            if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2)
186
                            {
187
                                // Reuse the current storage
188
                                DestStorage=m_Storage.m_dynSet;
189
                                m_Size=Other.m_Size;
190
                            }
191
                            else
192
                            {
193
                                // Allocate the new one
194
                                set_value_type* pTemp=new set_value_type[Other.m_Size];
195
                                DestStorage=pTemp;
196
                        
197
                                // Delete old storage if necessary
198
                                if(m_Storage.m_dynSet!=0)
199
                                {
200
                                    delete [] m_Storage.m_dynSet;
201
                                }
202
                                // Store the new storage
203
                                m_Storage.m_dynSet=pTemp;
204
                                // Set new size
205
                                m_Size=Other.m_Size;
206
                            }
207
                        }
208
                    }
209
210
                    // Copy the data
211
                    ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
212
213
                    return *this;
214
                }
215
216
                // Operation
217
                template<typename Char2T>
218
                bool operator()( Char2T Ch ) const
219
375
                {
220
375
                    const set_value_type* Storage=
221
375
                        (use_fixed_storage(m_Size))
222
375
                        ? &m_Storage.m_fixSet[0]
223
375
                        : m_Storage.m_dynSet;
224
225
375
                    return ::std::binary_search(Storage, Storage+m_Size, Ch);
226
375
                }
227
            private:
228
                // check if the size is eligible for fixed storage
229
                static bool use_fixed_storage(std::size_t size)
230
657
                {
231
657
                    return size<=sizeof(set_value_type*)*2;
232
657
                }
233
234
235
            private:
236
                // storage
237
                // The actual used storage is selected on the type
238
                union
239
                {
240
                    set_value_type* m_dynSet;
241
                    set_value_type m_fixSet[sizeof(set_value_type*)*2];
242
                } 
243
                m_Storage;
244
        
245
                // storage size
246
                ::std::size_t m_Size;
247
            };
248
249
            // is_from_range functor
250
            /*
251
                returns true if the value is from the specified range.
252
                (i.e. x>=From && x>=To)
253
            */
254
            template<typename CharT>
255
            struct is_from_rangeF :
256
                public predicate_facade< is_from_rangeF<CharT> >
257
            {
258
                // Boost.ResultOf support
259
                typedef bool result_type;
260
261
                // Constructor
262
                is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
263
264
                // Operation
265
                template<typename Char2T>
266
                bool operator()( Char2T Ch ) const
267
                {
268
                    return ( m_From <= Ch ) && ( Ch <= m_To );
269
                }
270
271
            private:
272
                CharT m_From;
273
                CharT m_To;
274
            };
275
276
            // class_and composition predicate
277
            template<typename Pred1T, typename Pred2T>
278
            struct pred_andF :
279
                public predicate_facade< pred_andF<Pred1T,Pred2T> >
280
            {
281
            public:
282
283
                // Boost.ResultOf support
284
                typedef bool result_type;
285
286
                // Constructor
287
                pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
288
                    m_Pred1(Pred1), m_Pred2(Pred2) {}
289
290
                // Operation
291
                template<typename CharT>
292
                bool operator()( CharT Ch ) const
293
                {
294
                    return m_Pred1(Ch) && m_Pred2(Ch);
295
                }
296
297
            private:
298
                Pred1T m_Pred1;
299
                Pred2T m_Pred2;
300
            };
301
302
            // class_or composition predicate
303
            template<typename Pred1T, typename Pred2T>
304
            struct pred_orF :
305
                public predicate_facade< pred_orF<Pred1T,Pred2T> >
306
            {
307
            public:
308
                // Boost.ResultOf support
309
                typedef bool result_type;
310
311
                // Constructor
312
                pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
313
                    m_Pred1(Pred1), m_Pred2(Pred2) {}
314
315
                // Operation
316
                template<typename CharT>
317
                bool operator()( CharT Ch ) const
318
                {
319
                    return m_Pred1(Ch) || m_Pred2(Ch);
320
                }
321
322
            private:
323
                Pred1T m_Pred1;
324
                Pred2T m_Pred2;
325
            };
326
327
            // class_not composition predicate
328
            template< typename PredT >
329
            struct pred_notF :
330
                public predicate_facade< pred_notF<PredT> >
331
            {
332
            public:
333
                // Boost.ResultOf support
334
                typedef bool result_type;
335
336
                // Constructor
337
                pred_notF( PredT Pred ) : m_Pred(Pred) {}
338
339
                // Operation
340
                template<typename CharT>
341
                bool operator()( CharT Ch ) const
342
                {
343
                    return !m_Pred(Ch);
344
                }
345
346
            private:
347
                PredT m_Pred;
348
            };
349
350
        } // namespace detail
351
    } // namespace algorithm
352
} // namespace boost
353
354
355
#endif  // BOOST_STRING_CLASSIFICATION_DETAIL_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/find_format_all.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library find_format_all.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
12
#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <boost/range/iterator_range_core.hpp>
16
#include <boost/range/const_iterator.hpp>
17
#include <boost/range/value_type.hpp>
18
#include <boost/algorithm/string/detail/find_format_store.hpp>
19
#include <boost/algorithm/string/detail/replace_storage.hpp>
20
21
#include <deque>
22
23
namespace boost {
24
    namespace algorithm {
25
        namespace detail {
26
27
// find_format_all_copy (iterator variant) implementation ---------------------------//
28
29
           template< 
30
                typename OutputIteratorT,
31
                typename InputT,
32
                typename FinderT,
33
                typename FormatterT,
34
                typename FindResultT,
35
                typename FormatResultT >
36
            inline OutputIteratorT find_format_all_copy_impl2(
37
                OutputIteratorT Output,
38
                const InputT& Input,
39
                FinderT Finder,
40
                FormatterT Formatter,
41
                const FindResultT& FindResult,
42
                const FormatResultT& FormatResult )
43
            {       
44
                typedef BOOST_STRING_TYPENAME 
45
                    range_const_iterator<InputT>::type input_iterator_type; 
46
47
                typedef find_format_store<
48
                        input_iterator_type, 
49
                        FormatterT,
50
                        FormatResultT > store_type;
51
52
                // Create store for the find result
53
                store_type M( FindResult, FormatResult, Formatter );
54
55
                // Initialize last match
56
                input_iterator_type LastMatch=::boost::begin(Input);
57
58
                // Iterate through all matches
59
                while( M )
60
                {
61
                    // Copy the beginning of the sequence
62
                    Output = std::copy( LastMatch, M.begin(), Output );
63
                    // Copy formatted result
64
                    Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output );
65
66
                    // Proceed to the next match
67
                    LastMatch=M.end();
68
                    M=Finder( LastMatch, ::boost::end(Input) );
69
                }
70
71
                // Copy the rest of the sequence
72
                Output = std::copy( LastMatch, ::boost::end(Input), Output );
73
74
                return Output;
75
            }
76
77
            template< 
78
                typename OutputIteratorT,
79
                typename InputT,
80
                typename FinderT,
81
                typename FormatterT,
82
                typename FindResultT >
83
            inline OutputIteratorT find_format_all_copy_impl(
84
                OutputIteratorT Output,
85
                const InputT& Input,
86
                FinderT Finder,
87
                FormatterT Formatter,
88
                const FindResultT& FindResult )
89
            {   
90
                if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
91
                    return ::boost::algorithm::detail::find_format_all_copy_impl2( 
92
                        Output,
93
                        Input,
94
                        Finder,
95
                        Formatter,
96
                        FindResult,
97
                        Formatter(FindResult) );
98
                } else {
99
                    return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
100
                }
101
            }
102
103
 // find_format_all_copy implementation ----------------------------------------------//
104
105
           template< 
106
                typename InputT, 
107
                typename FinderT,
108
                typename FormatterT,
109
                typename FindResultT,
110
                typename FormatResultT >
111
            inline InputT find_format_all_copy_impl2(
112
                const InputT& Input,
113
                FinderT Finder,
114
                FormatterT Formatter,
115
                const FindResultT& FindResult,
116
                const FormatResultT& FormatResult)
117
            {
118
                typedef BOOST_STRING_TYPENAME 
119
                    range_const_iterator<InputT>::type input_iterator_type; 
120
121
                typedef find_format_store<
122
                        input_iterator_type, 
123
                        FormatterT,
124
                        FormatResultT > store_type;
125
126
                // Create store for the find result
127
                store_type M( FindResult, FormatResult, Formatter );
128
129
                // Initialize last match
130
                input_iterator_type LastMatch=::boost::begin(Input);
131
132
                // Output temporary
133
                InputT Output;
134
135
                // Iterate through all matches
136
                while( M )
137
                {
138
                    // Copy the beginning of the sequence
139
                    boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, M.begin() );
140
                    // Copy formatted result
141
                    boost::algorithm::detail::insert( Output, ::boost::end(Output), M.format_result() );
142
143
                    // Proceed to the next match
144
                    LastMatch=M.end();
145
                    M=Finder( LastMatch, ::boost::end(Input) );
146
                }
147
148
                // Copy the rest of the sequence
149
                ::boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, ::boost::end(Input) );
150
151
                return Output;
152
            }
153
154
            template< 
155
                typename InputT, 
156
                typename FinderT,
157
                typename FormatterT,
158
                typename FindResultT >
159
            inline InputT find_format_all_copy_impl(
160
                const InputT& Input,
161
                FinderT Finder,
162
                FormatterT Formatter,
163
                const FindResultT& FindResult)
164
            {
165
                if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
166
                    return ::boost::algorithm::detail::find_format_all_copy_impl2(
167
                        Input,
168
                        Finder,
169
                        Formatter,
170
                        FindResult,
171
                        Formatter(FindResult) );
172
                } else {
173
                    return Input;
174
                }
175
            }
176
177
 // find_format_all implementation ------------------------------------------------//
178
        
179
            template<
180
                typename InputT,
181
                typename FinderT,
182
                typename FormatterT,
183
                typename FindResultT,
184
                typename FormatResultT >
185
            inline void find_format_all_impl2( 
186
                InputT& Input,
187
                FinderT Finder,
188
                FormatterT Formatter,
189
                FindResultT FindResult,
190
                FormatResultT FormatResult)
191
15
            {
192
15
                typedef BOOST_STRING_TYPENAME 
193
15
                    range_iterator<InputT>::type input_iterator_type; 
194
15
                typedef find_format_store<
195
15
                        input_iterator_type, 
196
15
                        FormatterT,
197
15
                        FormatResultT > store_type;
198
199
                // Create store for the find result
200
15
                store_type M( FindResult, FormatResult, Formatter );
201
          
202
                // Instantiate replacement storage
203
15
                std::deque<
204
15
                    BOOST_STRING_TYPENAME range_value<InputT>::type> Storage;
205
206
                // Initialize replacement iterators
207
15
                input_iterator_type InsertIt=::boost::begin(Input);
208
15
                input_iterator_type SearchIt=::boost::begin(Input);
209
                
210
30
                while( M )
211
15
                {
212
                    // process the segment
213
15
                    InsertIt=process_segment( 
214
15
                        Storage,
215
15
                        Input,
216
15
                        InsertIt,
217
15
                        SearchIt,
218
15
                        M.begin() );
219
                    
220
                    // Adjust search iterator
221
15
                    SearchIt=M.end();
222
223
                    // Copy formatted replace to the storage
224
15
                    ::boost::algorithm::detail::copy_to_storage( Storage, M.format_result() );
225
226
                    // Find range for a next match
227
15
                    M=Finder( SearchIt, ::boost::end(Input) );
228
15
                }
229
230
                // process the last segment
231
15
                InsertIt=::boost::algorithm::detail::process_segment( 
232
15
                    Storage,
233
15
                    Input,
234
15
                    InsertIt,
235
15
                    SearchIt,
236
15
                    ::boost::end(Input) );
237
                
238
15
                if ( Storage.empty() )
239
15
                {
240
                    // Truncate input
241
15
                    ::boost::algorithm::detail::erase( Input, InsertIt, ::boost::end(Input) );
242
15
                }
243
0
                else
244
0
                {
245
                    // Copy remaining data to the end of input
246
0
                    ::boost::algorithm::detail::insert( Input, ::boost::end(Input), Storage.begin(), Storage.end() );
247
0
                }
248
15
            }
249
250
            template<
251
                typename InputT,
252
                typename FinderT,
253
                typename FormatterT,
254
                typename FindResultT >
255
            inline void find_format_all_impl( 
256
                InputT& Input,
257
                FinderT Finder,
258
                FormatterT Formatter,
259
                FindResultT FindResult)
260
15
            {
261
15
                if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
262
15
                    ::boost::algorithm::detail::find_format_all_impl2(
263
15
                        Input,
264
15
                        Finder,
265
15
                        Formatter,
266
15
                        FindResult,
267
15
                        Formatter(FindResult) );
268
15
                }
269
15
            }
270
271
        } // namespace detail
272
    } // namespace algorithm
273
} // namespace boost
274
275
#endif  // BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/find_format_store.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library find_format_store.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
12
#define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <boost/range/iterator_range_core.hpp>
16
17
namespace boost {
18
    namespace algorithm {
19
        namespace detail {
20
21
//  temporary format and find result storage --------------------------------//
22
23
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
24
#pragma warning(push)
25
#pragma warning(disable:4512) //assignment operator could not be generated
26
#endif
27
            template< 
28
                typename ForwardIteratorT,
29
                typename FormatterT,
30
                typename FormatResultT >
31
            class find_format_store : 
32
                public iterator_range<ForwardIteratorT>
33
            {
34
            public:
35
                // typedefs
36
                typedef iterator_range<ForwardIteratorT> base_type;
37
                typedef FormatterT  formatter_type;
38
                typedef FormatResultT format_result_type;
39
                
40
            public:
41
                // Construction
42
                find_format_store( 
43
                        const base_type& FindResult,
44
                        const format_result_type& FormatResult,
45
                        const formatter_type& Formatter ) :
46
                    base_type(FindResult),
47
                    m_FormatResult(FormatResult),
48
15
                    m_Formatter(Formatter) {}
49
50
                // Assignment
51
                template< typename FindResultT >
52
                find_format_store& operator=( FindResultT FindResult )
53
15
                {
54
15
                    iterator_range<ForwardIteratorT>::operator=(FindResult);
55
15
                    if( !this->empty() ) {
56
0
                        m_FormatResult=m_Formatter(FindResult);
57
0
                    }
58
                    
59
15
                    return *this;
60
15
                }
61
62
                // Retrieve format result
63
                const format_result_type& format_result()
64
15
                {   
65
15
                    return m_FormatResult;
66
15
                }
67
68
            private:
69
                format_result_type m_FormatResult;
70
                const formatter_type& m_Formatter;
71
            };
72
73
            template<typename InputT, typename FindResultT>
74
            bool check_find_result(InputT&, FindResultT& FindResult)
75
15
            {
76
15
                typedef BOOST_STRING_TYPENAME 
77
15
                    range_const_iterator<InputT>::type input_iterator_type; 
78
15
                iterator_range<input_iterator_type> ResultRange(FindResult);
79
15
                return !ResultRange.empty();
80
15
            }
81
82
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
83
#pragma warning(pop)
84
#endif
85
        } // namespace detail
86
    } // namespace algorithm
87
} // namespace boost
88
89
#endif  // BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/find_iterator.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library find_iterator.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
12
#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <boost/range/iterator_range_core.hpp>
16
#include <boost/iterator/iterator_facade.hpp>
17
#include <boost/iterator/iterator_categories.hpp>
18
#include <boost/function.hpp>
19
20
namespace boost {
21
    namespace algorithm { 
22
        namespace detail {
23
24
//  find_iterator base -----------------------------------------------//
25
26
            // Find iterator base
27
            template<typename IteratorT>
28
            class find_iterator_base
29
            {
30
            protected:
31
                // typedefs
32
                typedef IteratorT input_iterator_type;
33
                typedef iterator_range<IteratorT> match_type;
34
                typedef function2<
35
                    match_type, 
36
                    input_iterator_type, 
37
                    input_iterator_type> finder_type;
38
                
39
            protected:
40
            // Protected construction/destruction
41
42
                // Default constructor
43
6
                find_iterator_base() {}
44
                // Copy construction
45
                find_iterator_base( const find_iterator_base& Other ) :
46
24
                    m_Finder(Other.m_Finder) {}
47
                
48
                // Constructor
49
                template<typename FinderT>
50
                find_iterator_base( FinderT Finder, int ) :
51
6
                    m_Finder(Finder) {}
52
53
                // Destructor
54
36
                ~find_iterator_base() {}
55
56
                // Find operation
57
                match_type do_find( 
58
                    input_iterator_type Begin,
59
                    input_iterator_type End ) const
60
60
                {
61
60
                    if (!m_Finder.empty())
62
60
                    {
63
60
                        return m_Finder(Begin,End);
64
60
                    }
65
0
                    else
66
0
                    {
67
0
                        return match_type(End,End);
68
0
                    }
69
60
                }
70
71
                // Check
72
                bool is_null() const
73
120
                {
74
120
                    return m_Finder.empty();
75
120
                }
76
77
            private:
78
                // Finder
79
                finder_type m_Finder;
80
            };
81
82
       } // namespace detail
83
    } // namespace algorithm
84
} // namespace boost
85
86
87
#endif  // BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/finder.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library finder.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2006.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FINDER_DETAIL_HPP
12
#define BOOST_STRING_FINDER_DETAIL_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <boost/algorithm/string/constants.hpp>
16
#include <iterator>
17
18
#include <boost/range/iterator_range_core.hpp>
19
#include <boost/range/begin.hpp>
20
#include <boost/range/end.hpp>
21
#include <boost/range/empty.hpp>
22
#include <boost/range/as_literal.hpp>
23
24
namespace boost {
25
    namespace algorithm {
26
        namespace detail {
27
28
29
//  find first functor -----------------------------------------------//
30
31
            // find a subsequence in the sequence ( functor )
32
            /*
33
                Returns a pair <begin,end> marking the subsequence in the sequence.
34
                If the find fails, functor returns <End,End>
35
            */
36
            template<typename SearchIteratorT,typename PredicateT>
37
            struct first_finderF
38
            {
39
                typedef SearchIteratorT search_iterator_type;
40
41
                // Construction
42
                template< typename SearchT >
43
                first_finderF( const SearchT& Search, PredicateT Comp ) :
44
15
                    m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
45
                first_finderF(
46
                        search_iterator_type SearchBegin,
47
                        search_iterator_type SearchEnd,
48
                        PredicateT Comp ) :
49
                    m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
50
51
                // Operation
52
                template< typename ForwardIteratorT >
53
                iterator_range<ForwardIteratorT>
54
                operator()(
55
                    ForwardIteratorT Begin,
56
                    ForwardIteratorT End ) const
57
30
                {
58
30
                    typedef iterator_range<ForwardIteratorT> result_type;
59
30
                    typedef ForwardIteratorT input_iterator_type;
60
61
                    // Outer loop
62
30
                    for(input_iterator_type OuterIt=Begin;
63
54
                        OuterIt!=End;
64
30
                        ++OuterIt)
65
39
                    {
66
                        // Sanity check
67
39
                        if( boost::empty(m_Search) )
68
0
                            return result_type( End, End );
69
70
39
                        input_iterator_type InnerIt=OuterIt;
71
39
                        search_iterator_type SubstrIt=m_Search.begin();
72
39
                        for(;
73
54
                            InnerIt!=End && SubstrIt!=m_Search.end();
74
39
                            ++InnerIt,++SubstrIt)
75
39
                        {
76
39
                            if( !( m_Comp(*InnerIt,*SubstrIt) ) )
77
24
                                break;
78
39
                        }
79
80
                        // Substring matching succeeded
81
39
                        if ( SubstrIt==m_Search.end() )
82
15
                            return result_type( OuterIt, InnerIt );
83
39
                    }
84
85
15
                    return result_type( End, End );
86
30
                }
_ZNK5boost9algorithm6detail13first_finderFIPKcNS0_8is_equalEEclINSt3__111__wrap_iterIPcEEEENS_14iterator_rangeIT_EESD_SD_
Line
Count
Source
57
30
                {
58
30
                    typedef iterator_range<ForwardIteratorT> result_type;
59
30
                    typedef ForwardIteratorT input_iterator_type;
60
61
                    // Outer loop
62
30
                    for(input_iterator_type OuterIt=Begin;
63
54
                        OuterIt!=End;
64
30
                        ++OuterIt)
65
39
                    {
66
                        // Sanity check
67
39
                        if( boost::empty(m_Search) )
68
0
                            return result_type( End, End );
69
70
39
                        input_iterator_type InnerIt=OuterIt;
71
39
                        search_iterator_type SubstrIt=m_Search.begin();
72
39
                        for(;
73
54
                            InnerIt!=End && SubstrIt!=m_Search.end();
74
39
                            ++InnerIt,++SubstrIt)
75
39
                        {
76
39
                            if( !( m_Comp(*InnerIt,*SubstrIt) ) )
77
24
                                break;
78
39
                        }
79
80
                        // Substring matching succeeded
81
39
                        if ( SubstrIt==m_Search.end() )
82
15
                            return result_type( OuterIt, InnerIt );
83
39
                    }
84
85
15
                    return result_type( End, End );
86
30
                }
Unexecuted instantiation: _ZNK5boost9algorithm6detail13first_finderFIPKcNS0_8is_equalEEclINSt3__111__wrap_iterIS4_EEEENS_14iterator_rangeIT_EESC_SC_
87
88
            private:
89
                iterator_range<search_iterator_type> m_Search;
90
                PredicateT m_Comp;
91
            };
92
93
//  find last functor -----------------------------------------------//
94
95
            // find the last match a subsequence in the sequence ( functor )
96
            /*
97
                Returns a pair <begin,end> marking the subsequence in the sequence.
98
                If the find fails, returns <End,End>
99
            */
100
            template<typename SearchIteratorT, typename PredicateT>
101
            struct last_finderF
102
            {
103
                typedef SearchIteratorT search_iterator_type;
104
                typedef first_finderF<
105
                    search_iterator_type,
106
                    PredicateT> first_finder_type;
107
108
                // Construction
109
                template< typename SearchT >
110
                last_finderF( const SearchT& Search, PredicateT Comp ) :
111
                    m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
112
                last_finderF(
113
                        search_iterator_type SearchBegin,
114
                        search_iterator_type SearchEnd,
115
                        PredicateT Comp ) :
116
                    m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
117
118
                // Operation
119
                template< typename ForwardIteratorT >
120
                iterator_range<ForwardIteratorT>
121
                operator()(
122
                    ForwardIteratorT Begin,
123
                    ForwardIteratorT End ) const
124
                {
125
                    typedef iterator_range<ForwardIteratorT> result_type;
126
127
                    if( boost::empty(m_Search) )
128
                        return result_type( End, End );
129
130
                    typedef BOOST_STRING_TYPENAME
131
                        std::iterator_traits<ForwardIteratorT>::iterator_category category;
132
133
                    return findit( Begin, End, category() );
134
                }
135
136
            private:
137
                // forward iterator
138
                template< typename ForwardIteratorT >
139
                iterator_range<ForwardIteratorT>
140
                findit(
141
                    ForwardIteratorT Begin,
142
                    ForwardIteratorT End,
143
                    std::forward_iterator_tag ) const
144
                {
145
                    typedef iterator_range<ForwardIteratorT> result_type;
146
147
                    first_finder_type first_finder(
148
                        m_Search.begin(), m_Search.end(), m_Comp );
149
150
                    result_type M=first_finder( Begin, End );
151
                    result_type Last=M;
152
153
                    while( M )
154
                    {
155
                        Last=M;
156
                        M=first_finder( ::boost::end(M), End );
157
                    }
158
159
                    return Last;
160
                }
161
162
                // bidirectional iterator
163
                template< typename ForwardIteratorT >
164
                iterator_range<ForwardIteratorT>
165
                findit(
166
                    ForwardIteratorT Begin,
167
                    ForwardIteratorT End,
168
                    std::bidirectional_iterator_tag ) const
169
                {
170
                    typedef iterator_range<ForwardIteratorT> result_type;
171
                    typedef ForwardIteratorT input_iterator_type;
172
173
                    // Outer loop
174
                    for(input_iterator_type OuterIt=End;
175
                        OuterIt!=Begin; )
176
                    {
177
                        input_iterator_type OuterIt2=--OuterIt;
178
179
                        input_iterator_type InnerIt=OuterIt2;
180
                        search_iterator_type SubstrIt=m_Search.begin();
181
                        for(;
182
                            InnerIt!=End && SubstrIt!=m_Search.end();
183
                            ++InnerIt,++SubstrIt)
184
                        {
185
                            if( !( m_Comp(*InnerIt,*SubstrIt) ) )
186
                                break;
187
                        }
188
189
                        // Substring matching succeeded
190
                        if( SubstrIt==m_Search.end() )
191
                            return result_type( OuterIt2, InnerIt );
192
                    }
193
194
                    return result_type( End, End );
195
                }
196
197
            private:
198
                iterator_range<search_iterator_type> m_Search;
199
                PredicateT m_Comp;
200
            };
201
202
//  find n-th functor -----------------------------------------------//
203
204
            // find the n-th match of a subsequence in the sequence ( functor )
205
            /*
206
                Returns a pair <begin,end> marking the subsequence in the sequence.
207
                If the find fails, returns <End,End>
208
            */
209
            template<typename SearchIteratorT, typename PredicateT>
210
            struct nth_finderF
211
            {
212
                typedef SearchIteratorT search_iterator_type;
213
                typedef first_finderF<
214
                    search_iterator_type,
215
                    PredicateT> first_finder_type;
216
                typedef last_finderF<
217
                    search_iterator_type,
218
                    PredicateT> last_finder_type;
219
220
                // Construction
221
                template< typename SearchT >
222
                nth_finderF(
223
                        const SearchT& Search,
224
                        int Nth,
225
                        PredicateT Comp) :
226
                    m_Search(::boost::begin(Search), ::boost::end(Search)),
227
                    m_Nth(Nth),
228
                    m_Comp(Comp) {}
229
                nth_finderF(
230
                        search_iterator_type SearchBegin,
231
                        search_iterator_type SearchEnd,
232
                        int Nth,
233
                        PredicateT Comp) :
234
                    m_Search(SearchBegin, SearchEnd),
235
                    m_Nth(Nth),
236
                    m_Comp(Comp) {}
237
238
                // Operation
239
                template< typename ForwardIteratorT >
240
                iterator_range<ForwardIteratorT>
241
                operator()(
242
                    ForwardIteratorT Begin,
243
                    ForwardIteratorT End ) const
244
                {
245
                    if(m_Nth>=0)
246
                    {
247
                        return find_forward(Begin, End, m_Nth);
248
                    }
249
                    else
250
                    {
251
                        return find_backward(Begin, End, -m_Nth);
252
                    }
253
254
                }
255
256
            private:
257
                // Implementation helpers
258
                template< typename ForwardIteratorT >
259
                iterator_range<ForwardIteratorT>
260
                find_forward(
261
                    ForwardIteratorT Begin,
262
                    ForwardIteratorT End,
263
                    unsigned int N) const
264
                {
265
                    typedef iterator_range<ForwardIteratorT> result_type;
266
267
                    // Sanity check
268
                    if( boost::empty(m_Search) )
269
                        return result_type( End, End );
270
271
                    // Instantiate find functor
272
                    first_finder_type first_finder(
273
                        m_Search.begin(), m_Search.end(), m_Comp );
274
275
                    result_type M( Begin, Begin );
276
277
                    for( unsigned int n=0; n<=N; ++n )
278
                    {
279
                        // find next match
280
                        M=first_finder( ::boost::end(M), End );
281
282
                        if ( !M )
283
                        {
284
                            // Subsequence not found, return
285
                            return M;
286
                        }
287
                    }
288
289
                    return M;
290
                }
291
292
                template< typename ForwardIteratorT >
293
                iterator_range<ForwardIteratorT>
294
                find_backward(
295
                    ForwardIteratorT Begin,
296
                    ForwardIteratorT End,
297
                    unsigned int N) const
298
                {
299
                    typedef iterator_range<ForwardIteratorT> result_type;
300
301
                    // Sanity check
302
                    if( boost::empty(m_Search) )
303
                        return result_type( End, End );
304
305
                    // Instantiate find functor
306
                    last_finder_type last_finder(
307
                        m_Search.begin(), m_Search.end(), m_Comp );
308
309
                    result_type M( End, End );
310
311
                    for( unsigned int n=1; n<=N; ++n )
312
                    {
313
                        // find next match
314
                        M=last_finder( Begin, ::boost::begin(M) );
315
316
                        if ( !M )
317
                        {
318
                            // Subsequence not found, return
319
                            return M;
320
                        }
321
                    }
322
323
                    return M;
324
                }
325
326
327
            private:
328
                iterator_range<search_iterator_type> m_Search;
329
                int m_Nth;
330
                PredicateT m_Comp;
331
            };
332
333
//  find head/tail implementation helpers ---------------------------//
334
335
            template<typename ForwardIteratorT>
336
                iterator_range<ForwardIteratorT>
337
            find_head_impl(
338
                ForwardIteratorT Begin,
339
                ForwardIteratorT End,
340
                unsigned int N,
341
                std::forward_iterator_tag )
342
            {
343
                typedef ForwardIteratorT input_iterator_type;
344
                typedef iterator_range<ForwardIteratorT> result_type;
345
346
                input_iterator_type It=Begin;
347
                for( unsigned int Index=0; Index<N && It!=End; ++Index,++It )
348
                    ;
349
350
                return result_type( Begin, It );
351
            }
352
353
            template< typename ForwardIteratorT >
354
                iterator_range<ForwardIteratorT>
355
            find_head_impl(
356
                ForwardIteratorT Begin,
357
                ForwardIteratorT End,
358
                unsigned int N,
359
                std::random_access_iterator_tag )
360
            {
361
                typedef iterator_range<ForwardIteratorT> result_type;
362
363
                if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
364
                    return result_type( Begin, End );
365
366
                return result_type(Begin,Begin+N);
367
            }
368
369
            // Find head implementation
370
            template<typename ForwardIteratorT>
371
                iterator_range<ForwardIteratorT>
372
            find_head_impl(
373
                ForwardIteratorT Begin,
374
                ForwardIteratorT End,
375
                unsigned int N )
376
            {
377
                typedef BOOST_STRING_TYPENAME
378
                    std::iterator_traits<ForwardIteratorT>::iterator_category category;
379
380
                return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() );
381
            }
382
383
            template< typename ForwardIteratorT >
384
                iterator_range<ForwardIteratorT>
385
            find_tail_impl(
386
                ForwardIteratorT Begin,
387
                ForwardIteratorT End,
388
                unsigned int N,
389
                std::forward_iterator_tag )
390
            {
391
                typedef ForwardIteratorT input_iterator_type;
392
                typedef iterator_range<ForwardIteratorT> result_type;
393
394
                unsigned int Index=0;
395
                input_iterator_type It=Begin;
396
                input_iterator_type It2=Begin;
397
398
                // Advance It2 by N increments
399
                for( Index=0; Index<N && It2!=End; ++Index,++It2 )
400
                    ;
401
402
                // Advance It, It2 to the end
403
                for(; It2!=End; ++It,++It2 )
404
                  ;
405
406
                return result_type( It, It2 );
407
            }
408
409
            template< typename ForwardIteratorT >
410
                iterator_range<ForwardIteratorT>
411
            find_tail_impl(
412
                ForwardIteratorT Begin,
413
                ForwardIteratorT End,
414
                unsigned int N,
415
                std::bidirectional_iterator_tag )
416
            {
417
                typedef ForwardIteratorT input_iterator_type;
418
                typedef iterator_range<ForwardIteratorT> result_type;
419
420
                input_iterator_type It=End;
421
                for( unsigned int Index=0; Index<N && It!=Begin; ++Index,--It )
422
                    ;
423
424
                return result_type( It, End );
425
            }
426
427
            template< typename ForwardIteratorT >
428
                iterator_range<ForwardIteratorT>
429
            find_tail_impl(
430
                ForwardIteratorT Begin,
431
                ForwardIteratorT End,
432
                unsigned int N,
433
                std::random_access_iterator_tag )
434
            {
435
                typedef iterator_range<ForwardIteratorT> result_type;
436
437
                if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
438
                    return result_type( Begin, End );
439
440
                return result_type( End-N, End );
441
            }
442
443
                        // Operation
444
            template< typename ForwardIteratorT >
445
            iterator_range<ForwardIteratorT>
446
            find_tail_impl(
447
                ForwardIteratorT Begin,
448
                ForwardIteratorT End,
449
                unsigned int N )
450
            {
451
                typedef BOOST_STRING_TYPENAME
452
                    std::iterator_traits<ForwardIteratorT>::iterator_category category;
453
454
                return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() );
455
            }
456
457
458
459
//  find head functor -----------------------------------------------//
460
461
462
            // find a head in the sequence ( functor )
463
            /*
464
                This functor find a head of the specified range. For
465
                a specified N, the head is a subsequence of N starting
466
                elements of the range.
467
            */
468
            struct head_finderF
469
            {
470
                // Construction
471
0
                head_finderF( int N ) : m_N(N) {}
472
473
                // Operation
474
                template< typename ForwardIteratorT >
475
                iterator_range<ForwardIteratorT>
476
                operator()(
477
                    ForwardIteratorT Begin,
478
                    ForwardIteratorT End ) const
479
                {
480
                    if(m_N>=0)
481
                    {
482
                        return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N );
483
                    }
484
                    else
485
                    {
486
                        iterator_range<ForwardIteratorT> Res=
487
                            ::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N );
488
489
                        return ::boost::make_iterator_range(Begin, Res.begin());
490
                    }
491
                }
492
493
            private:
494
                int m_N;
495
            };
496
497
//  find tail functor -----------------------------------------------//
498
499
500
            // find a tail in the sequence ( functor )
501
            /*
502
                This functor find a tail of the specified range. For
503
                a specified N, the head is a subsequence of N starting
504
                elements of the range.
505
            */
506
            struct tail_finderF
507
            {
508
                // Construction
509
0
                tail_finderF( int N ) : m_N(N) {}
510
511
                // Operation
512
                template< typename ForwardIteratorT >
513
                iterator_range<ForwardIteratorT>
514
                operator()(
515
                    ForwardIteratorT Begin,
516
                    ForwardIteratorT End ) const
517
                {
518
                    if(m_N>=0)
519
                    {
520
                        return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N );
521
                    }
522
                    else
523
                    {
524
                        iterator_range<ForwardIteratorT> Res=
525
                            ::boost::algorithm::detail::find_head_impl( Begin, End, -m_N );
526
527
                        return ::boost::make_iterator_range(Res.end(), End);
528
                    }
529
                }
530
531
            private:
532
                int m_N;
533
            };
534
535
//  find token functor -----------------------------------------------//
536
537
            // find a token in a sequence ( functor )
538
            /*
539
                This find functor finds a token specified be a predicate
540
                in a sequence. It is equivalent of std::find algorithm,
541
                with an exception that it return range instead of a single
542
                iterator.
543
544
                If bCompress is set to true, adjacent matching tokens are
545
                concatenated into one match.
546
            */
547
            template< typename PredicateT >
548
            struct token_finderF
549
            {
550
                // Construction
551
                token_finderF(
552
                    PredicateT Pred,
553
                    token_compress_mode_type eCompress=token_compress_off ) :
554
6
                        m_Pred(Pred), m_eCompress(eCompress) {}
555
556
                // Operation
557
                template< typename ForwardIteratorT >
558
                iterator_range<ForwardIteratorT>
559
                operator()(
560
                    ForwardIteratorT Begin,
561
                    ForwardIteratorT End ) const
562
60
                {
563
60
                    typedef iterator_range<ForwardIteratorT> result_type;
564
565
60
                    ForwardIteratorT It=std::find_if( Begin, End, m_Pred );
566
567
60
                    if( It==End )
568
12
                    {
569
12
                        return result_type( End, End );
570
12
                    }
571
48
                    else
572
48
                    {
573
48
                        ForwardIteratorT It2=It;
574
575
48
                        if( m_eCompress==token_compress_on )
576
33
                        {
577
                            // Find first non-matching character
578
66
                            while( It2!=End && m_Pred(*It2) ) ++It2;
579
33
                        }
580
15
                        else
581
15
                        {
582
                            // Advance by one position
583
15
                            ++It2;
584
15
                        }
585
586
48
                        return result_type( It, It2 );
587
48
                    }
588
60
                }
589
590
            private:
591
                PredicateT m_Pred;
592
                token_compress_mode_type m_eCompress;
593
            };
594
595
//  find range functor -----------------------------------------------//
596
597
            // find a range in the sequence ( functor )
598
            /*
599
                This functor actually does not perform any find operation.
600
                It always returns given iterator range as a result.
601
            */
602
            template<typename ForwardIterator1T>
603
            struct range_finderF
604
            {
605
                typedef ForwardIterator1T input_iterator_type;
606
                typedef iterator_range<input_iterator_type> result_type;
607
608
                // Construction
609
                range_finderF(
610
                    input_iterator_type Begin,
611
                    input_iterator_type End ) : m_Range(Begin, End) {}
612
613
                range_finderF(const iterator_range<input_iterator_type>& Range) :
614
                    m_Range(Range) {}
615
616
                // Operation
617
                template< typename ForwardIterator2T >
618
                iterator_range<ForwardIterator2T>
619
                operator()(
620
                    ForwardIterator2T,
621
                    ForwardIterator2T ) const
622
                {
623
#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 ) 
624
                    return iterator_range<const ForwardIterator2T>(this->m_Range);
625
#else
626
                    return m_Range;
627
#endif
628
                }
629
630
            private:
631
                iterator_range<input_iterator_type> m_Range;
632
            };
633
634
635
        } // namespace detail
636
    } // namespace algorithm
637
} // namespace boost
638
639
#endif  // BOOST_STRING_FINDER_DETAIL_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/formatter.hpp
Line
Count
Source
1
//  Boost string_algo library formatter.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FORMATTER_DETAIL_HPP
12
#define BOOST_STRING_FORMATTER_DETAIL_HPP
13
14
15
#include <boost/range/iterator_range_core.hpp>
16
#include <boost/range/begin.hpp>
17
#include <boost/range/end.hpp>
18
#include <boost/range/const_iterator.hpp>
19
20
#include <boost/algorithm/string/detail/util.hpp>
21
22
//  generic replace functors -----------------------------------------------//
23
24
namespace boost {
25
    namespace algorithm {
26
        namespace detail {
27
28
//  const format functor ----------------------------------------------------//
29
30
            // constant format functor
31
            template<typename RangeT>
32
            struct const_formatF
33
            {
34
            private:
35
                typedef BOOST_STRING_TYPENAME
36
                    range_const_iterator<RangeT>::type format_iterator;
37
                typedef iterator_range<format_iterator> result_type;
38
            
39
            public:
40
                // Construction
41
                const_formatF(const RangeT& Format) :
42
15
                    m_Format(::boost::begin(Format), ::boost::end(Format)) {}
43
44
                // Operation
45
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
46
                template<typename Range2T>
47
                result_type& operator()(const Range2T&)
48
                {
49
                    return m_Format;
50
                }
51
#endif
52
53
                template<typename Range2T>
54
                const result_type& operator()(const Range2T&) const
55
15
                {
56
15
                    return m_Format;
57
15
                }
_ZNK5boost9algorithm6detail13const_formatFINS_14iterator_rangeIPKcEEEclINS3_INSt3__111__wrap_iterIPcEEEEEERKS6_RKT_
Line
Count
Source
55
15
                {
56
15
                    return m_Format;
57
15
                }
Unexecuted instantiation: _ZNK5boost9algorithm6detail13const_formatFINS_14iterator_rangeIPKcEEEclINS3_INSt3__111__wrap_iterIS5_EEEEEERKS6_RKT_
58
59
            private:
60
                result_type m_Format;
61
            };
62
63
//  identity format functor ----------------------------------------------------//
64
65
            // identity format functor
66
            template<typename RangeT>
67
            struct identity_formatF
68
            {
69
                // Operation
70
                template< typename Range2T >
71
                const RangeT& operator()(const Range2T& Replace) const
72
                {
73
                    return RangeT(::boost::begin(Replace), ::boost::end(Replace));
74
                }
75
            };
76
77
//  empty format functor ( used by erase ) ------------------------------------//
78
        
79
            // empty format functor
80
            template< typename CharT >
81
            struct empty_formatF
82
            {
83
                template< typename ReplaceT >
84
                empty_container<CharT> operator()(const ReplaceT&) const
85
                {
86
                    return empty_container<CharT>();
87
                }
88
            };
89
90
//  dissect format functor ----------------------------------------------------//
91
92
            // dissect format functor
93
            template<typename FinderT>
94
            struct dissect_formatF
95
            {
96
            public:
97
                // Construction
98
                dissect_formatF(FinderT Finder) :
99
                  m_Finder(Finder) {}
100
101
                  // Operation
102
                  template<typename RangeT>
103
                  inline iterator_range< 
104
                      BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
105
                  operator()(const RangeT& Replace) const
106
                  {
107
                      return m_Finder(::boost::begin(Replace), ::boost::end(Replace));
108
                  }
109
110
            private:
111
                FinderT m_Finder;
112
            };
113
114
115
        } // namespace detail
116
    } // namespace algorithm
117
} // namespace boost
118
119
#endif  // BOOST_STRING_FORMATTER_DETAIL_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/replace_storage.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library replace_storage.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
12
#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <algorithm>
16
#include <boost/mpl/bool.hpp>
17
#include <boost/algorithm/string/sequence_traits.hpp>
18
#include <boost/algorithm/string/detail/sequence.hpp>
19
20
namespace boost {
21
    namespace algorithm {
22
        namespace detail {
23
24
//  storage handling routines -----------------------------------------------//
25
            
26
            template< typename StorageT, typename OutputIteratorT >
27
            inline OutputIteratorT move_from_storage(
28
                StorageT& Storage,
29
                OutputIteratorT DestBegin,
30
                OutputIteratorT DestEnd )
31
30
            {
32
30
                OutputIteratorT OutputIt=DestBegin;
33
                
34
30
                while( !Storage.empty() && OutputIt!=DestEnd )
35
0
                {
36
0
                    *OutputIt=Storage.front();
37
0
                    Storage.pop_front();
38
0
                    ++OutputIt;
39
0
                }
40
41
30
                return OutputIt;
42
30
            }
43
44
            template< typename StorageT, typename WhatT >
45
            inline void copy_to_storage(
46
                StorageT& Storage,
47
                const WhatT& What )
48
15
            {
49
15
                Storage.insert( Storage.end(), ::boost::begin(What), ::boost::end(What) );
50
15
            }
51
52
53
//  process segment routine -----------------------------------------------//
54
55
            template< bool HasStableIterators >
56
            struct process_segment_helper
57
            {
58
                // Optimized version of process_segment for generic sequence
59
                template< 
60
                    typename StorageT,
61
                    typename InputT,
62
                    typename ForwardIteratorT >
63
                ForwardIteratorT operator()(
64
                    StorageT& Storage,
65
                    InputT& /*Input*/,
66
                    ForwardIteratorT InsertIt,
67
                    ForwardIteratorT SegmentBegin,
68
                    ForwardIteratorT SegmentEnd )
69
30
                {
70
                    // Copy data from the storage until the beginning of the segment
71
30
                    ForwardIteratorT It=::boost::algorithm::detail::move_from_storage( Storage, InsertIt, SegmentBegin );
72
73
                    // 3 cases are possible :
74
                    //   a) Storage is empty, It==SegmentBegin
75
                    //   b) Storage is empty, It!=SegmentBegin
76
                    //   c) Storage is not empty
77
78
30
                    if( Storage.empty() )
79
30
                    {
80
30
                        if( It==SegmentBegin )
81
15
                        {
82
                            // Case a) everything is grand, just return end of segment
83
15
                            return SegmentEnd;
84
15
                        }
85
15
                        else
86
15
                        {
87
                            // Case b) move the segment backwards
88
15
                            return std::copy( SegmentBegin, SegmentEnd, It );
89
15
                        }
90
30
                    }
91
0
                    else
92
0
                    {
93
                        // Case c) -> shift the segment to the left and keep the overlap in the storage
94
0
                        while( It!=SegmentEnd )
95
0
                        {
96
                            // Store value into storage
97
0
                            Storage.push_back( *It );
98
                            // Get the top from the storage and put it here
99
0
                            *It=Storage.front();
100
0
                            Storage.pop_front();
101
102
                            // Advance
103
0
                            ++It;
104
0
                        }
105
106
0
                        return It;
107
0
                    }
108
30
                }
109
            };
110
111
            template<>
112
            struct process_segment_helper< true >
113
            {
114
                // Optimized version of process_segment for list-like sequence
115
                template< 
116
                    typename StorageT,
117
                    typename InputT,
118
                    typename ForwardIteratorT >
119
                ForwardIteratorT operator()(
120
                    StorageT& Storage,
121
                    InputT& Input,
122
                    ForwardIteratorT InsertIt,
123
                    ForwardIteratorT SegmentBegin,
124
                    ForwardIteratorT SegmentEnd )
125
126
                {
127
                    // Call replace to do the job
128
                    ::boost::algorithm::detail::replace( Input, InsertIt, SegmentBegin, Storage );
129
                    // Empty the storage
130
                    Storage.clear();
131
                    // Iterators were not changed, simply return the end of segment
132
                    return SegmentEnd;
133
                }
134
            };
135
136
            // Process one segment in the replace_all algorithm
137
            template< 
138
                typename StorageT,
139
                typename InputT,
140
                typename ForwardIteratorT >
141
            inline ForwardIteratorT process_segment(
142
                StorageT& Storage,
143
                InputT& Input,
144
                ForwardIteratorT InsertIt,
145
                ForwardIteratorT SegmentBegin,
146
                ForwardIteratorT SegmentEnd )
147
30
            {
148
30
                return 
149
30
                    process_segment_helper< 
150
30
                        has_stable_iterators<InputT>::value>()(
151
30
                                Storage, Input, InsertIt, SegmentBegin, SegmentEnd );
152
30
            }
153
            
154
155
        } // namespace detail
156
    } // namespace algorithm
157
} // namespace boost
158
159
#endif  // BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/sequence.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library sequence.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP
12
#define BOOST_STRING_DETAIL_SEQUENCE_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <boost/mpl/bool.hpp>
16
#include <boost/mpl/logical.hpp>
17
#include <boost/range/begin.hpp>
18
#include <boost/range/end.hpp>
19
20
#include <boost/algorithm/string/sequence_traits.hpp>
21
22
namespace boost {
23
    namespace algorithm {
24
        namespace detail {
25
26
//  insert helpers  -------------------------------------------------//
27
        
28
            template< typename InputT, typename ForwardIteratorT >
29
            inline void insert(
30
                InputT& Input,
31
                BOOST_STRING_TYPENAME InputT::iterator At,
32
                ForwardIteratorT Begin,
33
                ForwardIteratorT End )
34
0
            {
35
0
                Input.insert( At, Begin, End );
36
0
            }
37
38
            template< typename InputT, typename InsertT >
39
            inline void insert(
40
                InputT& Input,
41
                BOOST_STRING_TYPENAME InputT::iterator At,
42
                const InsertT& Insert )
43
            {
44
                ::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) );
45
            }
46
           
47
//  erase helper  ---------------------------------------------------//
48
49
            // Erase a range in the sequence
50
            /*
51
                Returns the iterator pointing just after the erase subrange
52
            */
53
            template< typename InputT >
54
            inline typename InputT::iterator erase(
55
                InputT& Input,
56
                BOOST_STRING_TYPENAME InputT::iterator From,
57
                BOOST_STRING_TYPENAME InputT::iterator To )
58
15
            {
59
15
                return Input.erase( From, To );
60
15
            }
61
62
//  replace helper implementation  ----------------------------------//
63
64
            // Optimized version of replace for generic sequence containers
65
            // Assumption: insert and erase are expensive
66
            template< bool HasConstTimeOperations >
67
            struct replace_const_time_helper
68
            {
69
                template< typename InputT, typename ForwardIteratorT >
70
                void operator()(
71
                    InputT& Input,
72
                    BOOST_STRING_TYPENAME InputT::iterator From,
73
                    BOOST_STRING_TYPENAME InputT::iterator To,
74
                    ForwardIteratorT Begin,
75
                    ForwardIteratorT End )
76
                {
77
                    // Copy data to the container ( as much as possible )
78
                    ForwardIteratorT InsertIt=Begin;
79
                    BOOST_STRING_TYPENAME InputT::iterator InputIt=From;
80
                    for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ )
81
                    {
82
                        *InputIt=*InsertIt;
83
                    }
84
85
                    if ( InsertIt!=End )
86
                    {
87
                        // Replace sequence is longer, insert it
88
                        Input.insert( InputIt, InsertIt, End );
89
                    }
90
                    else
91
                    {
92
                        if ( InputIt!=To )
93
                        {
94
                            // Replace sequence is shorter, erase the rest
95
                            Input.erase( InputIt, To );
96
                        }
97
                    }
98
                }
99
            };
100
101
            template<>
102
            struct replace_const_time_helper< true >
103
            {
104
                // Const-time erase and insert methods -> use them
105
                template< typename InputT, typename ForwardIteratorT >
106
                void operator()(
107
                    InputT& Input,
108
                    BOOST_STRING_TYPENAME InputT::iterator From,
109
                    BOOST_STRING_TYPENAME InputT::iterator To,
110
                    ForwardIteratorT Begin,
111
                    ForwardIteratorT End ) 
112
                {
113
                    BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To );
114
                    if ( Begin!=End )
115
                    {
116
                        if(!Input.empty())
117
                        {
118
                            Input.insert( At, Begin, End );
119
                        }
120
                        else
121
                        {
122
                            Input.insert( Input.begin(), Begin, End );
123
                        }
124
                    }
125
                }
126
            };
127
128
            // No native replace method
129
            template< bool HasNative >
130
            struct replace_native_helper
131
            {
132
                template< typename InputT, typename ForwardIteratorT >
133
                void operator()(
134
                    InputT& Input,
135
                    BOOST_STRING_TYPENAME InputT::iterator From,
136
                    BOOST_STRING_TYPENAME InputT::iterator To,
137
                    ForwardIteratorT Begin,
138
                    ForwardIteratorT End ) 
139
                {
140
                    replace_const_time_helper< 
141
                        boost::mpl::and_<
142
                            has_const_time_insert<InputT>,
143
                            has_const_time_erase<InputT> >::value >()(
144
                        Input, From, To, Begin, End );
145
                }
146
            };
147
148
            // Container has native replace method
149
            template<>
150
            struct replace_native_helper< true >
151
            {
152
                template< typename InputT, typename ForwardIteratorT >
153
                void operator()(
154
                    InputT& Input,
155
                    BOOST_STRING_TYPENAME InputT::iterator From,
156
                    BOOST_STRING_TYPENAME InputT::iterator To,
157
                    ForwardIteratorT Begin,
158
                    ForwardIteratorT End )
159
                {
160
                    Input.replace( From, To, Begin, End );
161
                }
162
            };
163
164
//  replace helper  -------------------------------------------------//
165
        
166
            template< typename InputT, typename ForwardIteratorT >
167
            inline void replace(
168
                InputT& Input,
169
                BOOST_STRING_TYPENAME InputT::iterator From,
170
                BOOST_STRING_TYPENAME InputT::iterator To,
171
                ForwardIteratorT Begin,
172
                ForwardIteratorT End )
173
            {
174
                replace_native_helper< has_native_replace<InputT>::value >()(
175
                    Input, From, To, Begin, End );
176
            }
177
178
            template< typename InputT, typename InsertT >
179
            inline void replace(
180
                InputT& Input,
181
                BOOST_STRING_TYPENAME InputT::iterator From,
182
                BOOST_STRING_TYPENAME InputT::iterator To,
183
                const InsertT& Insert )
184
            {
185
                if(From!=To)
186
                {
187
                    ::boost::algorithm::detail::replace( Input, From, To, ::boost::begin(Insert), ::boost::end(Insert) );
188
                }
189
                else
190
                {
191
                    ::boost::algorithm::detail::insert( Input, From, ::boost::begin(Insert), ::boost::end(Insert) );
192
                }
193
            }
194
195
        } // namespace detail
196
    } // namespace algorithm
197
} // namespace boost
198
199
200
#endif  // BOOST_STRING_DETAIL_SEQUENCE_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/detail/util.hpp
Line
Count
Source
1
//  Boost string_algo library util.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_UTIL_DETAIL_HPP
12
#define BOOST_STRING_UTIL_DETAIL_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <functional>
16
#include <boost/range/iterator_range_core.hpp>
17
18
namespace boost {
19
    namespace algorithm {
20
        namespace detail {
21
22
//  empty container  -----------------------------------------------//
23
24
            //  empty_container 
25
            /*
26
                This class represents always empty container,
27
                containing elements of type CharT.
28
29
                It is supposed to be used in a const version only
30
            */
31
            template< typename CharT >
32
            struct empty_container 
33
            {
34
                typedef empty_container<CharT> type;        
35
                typedef CharT value_type;
36
                typedef std::size_t size_type;
37
                typedef std::ptrdiff_t difference_type;
38
                typedef const value_type& reference;
39
                typedef const value_type& const_reference;
40
                typedef const value_type* iterator;
41
                typedef const value_type* const_iterator;
42
43
                
44
                // Operations
45
                const_iterator begin() const
46
                {
47
                    return reinterpret_cast<const_iterator>(0);
48
                }
49
50
                const_iterator end() const
51
                {
52
                    return reinterpret_cast<const_iterator>(0);
53
                }
54
55
                bool empty() const
56
                {
57
                    return false;
58
                }
59
60
                size_type size() const
61
                {
62
                    return 0;
63
                }
64
            };
65
    
66
//  bounded copy algorithm  -----------------------------------------------//
67
68
            // Bounded version of the std::copy algorithm
69
            template<typename InputIteratorT, typename OutputIteratorT>
70
            inline OutputIteratorT bounded_copy(
71
                InputIteratorT First, 
72
                InputIteratorT Last, 
73
                OutputIteratorT DestFirst,
74
                OutputIteratorT DestLast )
75
            {
76
                InputIteratorT InputIt=First;
77
                OutputIteratorT OutputIt=DestFirst;
78
                for(; InputIt!=Last && OutputIt!=DestLast; InputIt++, OutputIt++ )
79
                {
80
                    *OutputIt=*InputIt;
81
                }
82
83
                return OutputIt;
84
            }
85
86
//  iterator range utilities -----------------------------------------//
87
88
            // copy range functor
89
            template< 
90
                typename SeqT, 
91
                typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator >
92
            struct copy_iterator_rangeF
93
            {
94
                typedef iterator_range<IteratorT> argument_type;
95
                typedef SeqT result_type;
96
                SeqT operator()( const iterator_range<IteratorT>& Range ) const
97
54
                {
98
54
                    return copy_range<SeqT>(Range);
99
54
                }
100
            };
101
102
        } // namespace detail
103
    } // namespace algorithm
104
} // namespace boost
105
106
107
#endif  // BOOST_STRING_UTIL_DETAIL_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/find_format.hpp
Line
Count
Source
1
//  Boost string_algo library find_format.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FIND_FORMAT_HPP
12
#define BOOST_STRING_FIND_FORMAT_HPP
13
14
#include <deque>
15
#include <boost/range/iterator_range_core.hpp>
16
#include <boost/range/begin.hpp>
17
#include <boost/range/end.hpp>
18
#include <boost/range/const_iterator.hpp>
19
#include <boost/range/as_literal.hpp>
20
21
#include <boost/algorithm/string/concept.hpp>
22
#include <boost/algorithm/string/detail/find_format.hpp>
23
#include <boost/algorithm/string/detail/find_format_all.hpp>
24
25
/*! \file
26
    Defines generic replace algorithms. Each algorithm replaces
27
    part(s) of the input. The part to be replaced is looked up using a Finder object.
28
    Result of finding is then used by a Formatter object to generate the replacement.
29
*/
30
31
namespace boost {
32
    namespace algorithm {
33
34
// generic replace  -----------------------------------------------------------------//
35
36
        //! Generic replace algorithm
37
        /*!
38
            Use the Finder to search for a substring. Use the Formatter to format
39
            this substring and replace it in the input.
40
            The result is a modified copy of the input. It is returned as a sequence 
41
            or copied to the output iterator.
42
43
            \param Output An output iterator to which the result will be copied
44
            \param Input An input sequence
45
            \param Finder A Finder object used to search for a match to be replaced
46
            \param Formatter A Formatter object used to format a match
47
            \return An output iterator pointing just after the last inserted character or
48
                a modified copy of the input
49
50
            \note The second variant of this function provides the strong exception-safety guarantee
51
        */
52
        template< 
53
            typename OutputIteratorT,
54
            typename RangeT,
55
            typename FinderT,
56
            typename FormatterT>
57
        inline OutputIteratorT find_format_copy(
58
            OutputIteratorT Output,
59
            const RangeT& Input,
60
            FinderT Finder,
61
            FormatterT Formatter )
62
        {
63
            // Concept check
64
            BOOST_CONCEPT_ASSERT((
65
                FinderConcept<
66
                    FinderT,
67
                    BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
68
                ));
69
            BOOST_CONCEPT_ASSERT((
70
                FormatterConcept<
71
                    FormatterT,
72
                    FinderT,BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
73
                ));
74
75
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
76
77
            return detail::find_format_copy_impl(
78
                Output,
79
                lit_input,
80
                Formatter,
81
                Finder( ::boost::begin(lit_input), ::boost::end(lit_input) ) );
82
        }
83
84
        //! Generic replace algorithm
85
        /*!
86
            \overload
87
        */
88
        template< 
89
            typename SequenceT, 
90
            typename FinderT,
91
            typename FormatterT>
92
        inline SequenceT find_format_copy(
93
            const SequenceT& Input,
94
            FinderT Finder,
95
            FormatterT Formatter )
96
        {
97
            // Concept check
98
            BOOST_CONCEPT_ASSERT((
99
                FinderConcept<
100
                    FinderT,
101
                    BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
102
                ));
103
            BOOST_CONCEPT_ASSERT((
104
                FormatterConcept<
105
                    FormatterT,
106
                    FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
107
                ));
108
109
            return detail::find_format_copy_impl(
110
                Input,
111
                Formatter,
112
                Finder(::boost::begin(Input), ::boost::end(Input)));
113
        }
114
115
        //! Generic replace algorithm
116
        /*!
117
            Use the Finder to search for a substring. Use the Formatter to format
118
            this substring and replace it in the input. The input is modified in-place.
119
120
            \param Input An input sequence
121
            \param Finder A Finder object used to search for a match to be replaced
122
            \param Formatter A Formatter object used to format a match
123
        */
124
        template<
125
            typename SequenceT,
126
            typename FinderT,
127
            typename FormatterT>
128
        inline void find_format( 
129
            SequenceT& Input,
130
            FinderT Finder,
131
            FormatterT Formatter)
132
        {
133
            // Concept check
134
            BOOST_CONCEPT_ASSERT((
135
                FinderConcept<
136
                    FinderT,
137
                    BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
138
                ));
139
            BOOST_CONCEPT_ASSERT(( 
140
                FormatterConcept<
141
                    FormatterT,
142
                    FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
143
                ));
144
145
            detail::find_format_impl(
146
                Input,
147
                Formatter,
148
                Finder(::boost::begin(Input), ::boost::end(Input)));
149
        }
150
151
152
//  find_format_all generic ----------------------------------------------------------------//
153
154
        //! Generic replace all algorithm
155
        /*!
156
            Use the Finder to search for a substring. Use the Formatter to format
157
            this substring and replace it in the input. Repeat this for all matching
158
            substrings.
159
            The result is a modified copy of the input. It is returned as a sequence 
160
            or copied to the output iterator.
161
162
            \param Output An output iterator to which the result will be copied
163
            \param Input An input sequence
164
            \param Finder A Finder object used to search for a match to be replaced
165
            \param Formatter A Formatter object used to format a match
166
            \return An output iterator pointing just after the last inserted character or
167
                a modified copy of the input
168
169
             \note The second variant of this function provides the strong exception-safety guarantee
170
        */
171
        template< 
172
            typename OutputIteratorT,
173
            typename RangeT,
174
            typename FinderT,
175
            typename FormatterT>
176
        inline OutputIteratorT find_format_all_copy(
177
            OutputIteratorT Output,
178
            const RangeT& Input,
179
            FinderT Finder,
180
            FormatterT Formatter)
181
        {
182
            // Concept check
183
            BOOST_CONCEPT_ASSERT(( 
184
                FinderConcept<
185
                    FinderT,
186
                    BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
187
                ));
188
            BOOST_CONCEPT_ASSERT(( 
189
                FormatterConcept<
190
                    FormatterT,
191
                    FinderT,BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
192
                ));
193
194
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
195
196
            return detail::find_format_all_copy_impl(
197
                Output,
198
                lit_input,
199
                Finder,
200
                Formatter,
201
                Finder(::boost::begin(lit_input), ::boost::end(lit_input)));
202
        }
203
204
        //! Generic replace all algorithm
205
        /*!
206
            \overload
207
        */
208
        template< 
209
            typename SequenceT, 
210
            typename FinderT,
211
            typename FormatterT >
212
        inline SequenceT find_format_all_copy(
213
            const SequenceT& Input,
214
            FinderT Finder,
215
            FormatterT Formatter )
216
        {
217
            // Concept check
218
            BOOST_CONCEPT_ASSERT((
219
                FinderConcept<
220
                    FinderT,
221
                    BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
222
                ));
223
            BOOST_CONCEPT_ASSERT((
224
                FormatterConcept<
225
                    FormatterT,
226
                    FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
227
                ));
228
229
            return detail::find_format_all_copy_impl(
230
                Input,
231
                Finder,
232
                Formatter,
233
                Finder( ::boost::begin(Input), ::boost::end(Input) ) );
234
        }
235
236
        //! Generic replace all algorithm
237
        /*!
238
            Use the Finder to search for a substring. Use the Formatter to format
239
            this substring and replace it in the input. Repeat this for all matching
240
            substrings.The input is modified in-place.
241
242
            \param Input An input sequence
243
            \param Finder A Finder object used to search for a match to be replaced
244
            \param Formatter A Formatter object used to format a match
245
        */
246
        template<
247
            typename SequenceT,
248
            typename FinderT,
249
            typename FormatterT >
250
        inline void find_format_all( 
251
            SequenceT& Input,
252
            FinderT Finder,
253
            FormatterT Formatter )
254
15
        {
255
            // Concept check
256
15
            BOOST_CONCEPT_ASSERT((
257
15
                FinderConcept<
258
15
                    FinderT,
259
15
                    BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
260
15
                ));
261
15
            BOOST_CONCEPT_ASSERT((
262
15
                FormatterConcept<
263
15
                    FormatterT,
264
15
                    FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
265
15
                ));
266
267
15
            detail::find_format_all_impl(
268
15
                Input,
269
15
                Finder,
270
15
                Formatter,
271
15
                Finder(::boost::begin(Input), ::boost::end(Input)));
272
273
15
        }
274
275
    } // namespace algorithm
276
277
    // pull the names to the boost namespace
278
    using algorithm::find_format_copy;
279
    using algorithm::find_format;
280
    using algorithm::find_format_all_copy;
281
    using algorithm::find_format_all;
282
283
} // namespace boost
284
285
286
#endif  // BOOST_STRING_FIND_FORMAT_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/find_iterator.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library find_iterator.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2004.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FIND_ITERATOR_HPP
12
#define BOOST_STRING_FIND_ITERATOR_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <boost/iterator/iterator_facade.hpp>
16
#include <boost/iterator/iterator_categories.hpp>
17
18
#include <boost/range/iterator_range_core.hpp>
19
#include <boost/range/begin.hpp>
20
#include <boost/range/end.hpp>
21
#include <boost/range/iterator.hpp>
22
#include <boost/range/as_literal.hpp>
23
24
#include <boost/algorithm/string/detail/find_iterator.hpp>
25
26
/*! \file
27
    Defines find iterator classes. Find iterator repeatedly applies a Finder
28
    to the specified input string to search for matches. Dereferencing
29
    the iterator yields the current match or a range between the last and the current
30
    match depending on the iterator used.
31
*/
32
33
namespace boost {
34
    namespace algorithm { 
35
36
//  find_iterator -----------------------------------------------//
37
38
        //! find_iterator
39
        /*!    
40
            Find iterator encapsulates a Finder and allows
41
            for incremental searching in a string.
42
            Each increment moves the iterator to the next match.
43
44
            Find iterator is a readable forward traversal iterator.
45
46
            Dereferencing the iterator yields an iterator_range delimiting
47
            the current match.
48
        */
49
        template<typename IteratorT>
50
        class find_iterator : 
51
            public iterator_facade<
52
                find_iterator<IteratorT>,
53
                const iterator_range<IteratorT>,
54
                forward_traversal_tag >,
55
            private detail::find_iterator_base<IteratorT>
56
        {
57
        private:
58
            // facade support
59
            friend class ::boost::iterator_core_access;
60
61
        private:
62
        // typedefs
63
64
            typedef detail::find_iterator_base<IteratorT> base_type;
65
            typedef BOOST_STRING_TYPENAME 
66
                base_type::input_iterator_type input_iterator_type;
67
            typedef BOOST_STRING_TYPENAME 
68
                base_type::match_type match_type;
69
70
        public:
71
            //! Default constructor
72
            /*!
73
                Construct null iterator. All null iterators are equal.
74
75
                \post eof()==true
76
            */
77
            find_iterator() {}
78
79
            //! Copy constructor
80
            /*!
81
                Construct a copy of the find_iterator
82
            */
83
            find_iterator( const find_iterator& Other ) :
84
                base_type(Other),
85
                m_Match(Other.m_Match),
86
                m_End(Other.m_End) {}
87
88
            //! Constructor
89
            /*!
90
                Construct new find_iterator for a given finder
91
                and a range.
92
            */
93
            template<typename FinderT>
94
            find_iterator(
95
                    IteratorT Begin,
96
                    IteratorT End,
97
                    FinderT Finder ) :
98
                detail::find_iterator_base<IteratorT>(Finder,0),
99
                m_Match(Begin,Begin),
100
                m_End(End)
101
            {
102
                increment();
103
            }
104
105
            //! Constructor
106
            /*!
107
                Construct new find_iterator for a given finder
108
                and a range.
109
            */
110
            template<typename FinderT, typename RangeT>
111
            find_iterator(
112
                    RangeT& Col,
113
                    FinderT Finder ) :
114
                detail::find_iterator_base<IteratorT>(Finder,0)
115
            {
116
                iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
117
                m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
118
                m_End=::boost::end(lit_col);
119
120
                increment();
121
            }
122
123
        private:
124
        // iterator operations
125
126
            // dereference
127
            const match_type& dereference() const
128
            {
129
                return m_Match;
130
            }
131
132
            // increment
133
            void increment()
134
            {
135
                m_Match=this->do_find(m_Match.end(),m_End);
136
            }
137
138
            // comparison
139
            bool equal( const find_iterator& Other ) const
140
            {
141
                bool bEof=eof();
142
                bool bOtherEof=Other.eof();
143
144
                return bEof || bOtherEof ? bEof==bOtherEof :
145
                    (
146
                        m_Match==Other.m_Match &&
147
                        m_End==Other.m_End 
148
                    );
149
            }
150
151
        public:
152
        // operations
153
154
            //! Eof check
155
            /*!
156
                Check the eof condition. Eof condition means that
157
                there is nothing more to be searched i.e. find_iterator
158
                is after the last match.
159
            */
160
            bool eof() const
161
            {
162
                return 
163
                    this->is_null() || 
164
                    ( 
165
                        m_Match.begin() == m_End &&
166
                        m_Match.end() == m_End
167
                    );
168
            }
169
170
        private:
171
        // Attributes
172
            match_type m_Match;
173
            input_iterator_type m_End;
174
        };
175
176
        //! find iterator construction helper
177
        /*!
178
         *    Construct a find iterator to iterate through the specified string
179
         */
180
        template<typename RangeT, typename FinderT>
181
        inline find_iterator< 
182
            BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
183
        make_find_iterator(
184
            RangeT& Collection,
185
            FinderT Finder)
186
        {
187
            return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
188
                Collection, Finder);
189
        }
190
191
//  split iterator -----------------------------------------------//
192
193
        //! split_iterator
194
        /*!    
195
            Split iterator encapsulates a Finder and allows
196
            for incremental searching in a string.
197
            Unlike the find iterator, split iterator iterates
198
            through gaps between matches.
199
200
            Find iterator is a readable forward traversal iterator.
201
202
            Dereferencing the iterator yields an iterator_range delimiting
203
            the current match.
204
        */
205
        template<typename IteratorT>
206
        class split_iterator : 
207
            public iterator_facade<
208
                split_iterator<IteratorT>,
209
                const iterator_range<IteratorT>,
210
                forward_traversal_tag >,
211
            private detail::find_iterator_base<IteratorT>
212
        {
213
        private:
214
            // facade support
215
            friend class ::boost::iterator_core_access;
216
217
        private:
218
        // typedefs
219
220
            typedef detail::find_iterator_base<IteratorT> base_type;
221
            typedef BOOST_STRING_TYPENAME 
222
                base_type::input_iterator_type input_iterator_type;
223
            typedef BOOST_STRING_TYPENAME 
224
                base_type::match_type match_type;
225
226
        public:
227
            //! Default constructor
228
            /*!
229
                Construct null iterator. All null iterators are equal.
230
    
231
                \post eof()==true
232
            */
233
            split_iterator() :
234
                m_Next(),
235
                m_End(),
236
                m_bEof(true)
237
6
            {}
238
239
            //! Copy constructor
240
            /*!
241
                Construct a copy of the split_iterator
242
            */
243
            split_iterator( const split_iterator& Other ) :
244
                base_type(Other),
245
                m_Match(Other.m_Match),
246
                m_Next(Other.m_Next),
247
                m_End(Other.m_End),
248
                m_bEof(Other.m_bEof)
249
24
            {}
250
251
            //! Constructor
252
            /*!
253
                Construct new split_iterator for a given finder
254
                and a range.
255
            */
256
            template<typename FinderT>
257
            split_iterator(
258
                    IteratorT Begin,
259
                    IteratorT End,
260
                    FinderT Finder ) :
261
                detail::find_iterator_base<IteratorT>(Finder,0),
262
                m_Match(Begin,Begin),
263
                m_Next(Begin),
264
                m_End(End),
265
                m_bEof(false)
266
6
            {
267
                // force the correct behavior for empty sequences and yield at least one token
268
6
                if(Begin!=End)
269
6
                {
270
6
                    increment();
271
6
                }
272
6
            }
273
            //! Constructor
274
            /*!
275
                Construct new split_iterator for a given finder
276
                and a collection.
277
            */
278
            template<typename FinderT, typename RangeT>
279
            split_iterator(
280
                    RangeT& Col,
281
                    FinderT Finder ) :
282
                detail::find_iterator_base<IteratorT>(Finder,0),
283
                m_bEof(false)
284
            {
285
                iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
286
                m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
287
                m_Next=::boost::begin(lit_col);
288
                m_End=::boost::end(lit_col);
289
290
                // force the correct behavior for empty sequences and yield at least one token
291
                if(m_Next!=m_End)
292
                {
293
                    increment();
294
                }
295
            }
296
297
298
        private:
299
        // iterator operations
300
301
            // dereference
302
            const match_type& dereference() const
303
54
            {
304
54
                return m_Match;
305
54
            }
306
307
            // increment
308
            void increment()
309
60
            {
310
60
                match_type FindMatch=this->do_find( m_Next, m_End );
311
312
60
                if(FindMatch.begin()==m_End && FindMatch.end()==m_End)
313
12
                {
314
12
                    if(m_Match.end()==m_End)
315
6
                    {
316
                        // Mark iterator as eof
317
6
                        m_bEof=true;
318
6
                    }
319
12
                }
320
321
60
                m_Match=match_type( m_Next, FindMatch.begin() );
322
60
                m_Next=FindMatch.end();
323
60
            }
324
325
            // comparison
326
            bool equal( const split_iterator& Other ) const
327
60
            {
328
60
                bool bEof=eof();
329
60
                bool bOtherEof=Other.eof();
330
331
60
                return bEof || bOtherEof ? bEof==bOtherEof :
332
60
                    (
333
0
                        m_Match==Other.m_Match &&
334
0
                        m_Next==Other.m_Next &&
335
0
                        m_End==Other.m_End
336
0
                    );
337
60
            }
338
339
        public:
340
        // operations
341
342
            //! Eof check
343
            /*!
344
                Check the eof condition. Eof condition means that
345
                there is nothing more to be searched i.e. find_iterator
346
                is after the last match.
347
            */
348
            bool eof() const
349
120
            {
350
120
                return this->is_null() || m_bEof;
351
120
            }
352
353
        private:
354
        // Attributes
355
            match_type m_Match;
356
            input_iterator_type m_Next;
357
            input_iterator_type m_End;
358
            bool m_bEof;
359
        };
360
361
        //! split iterator construction helper
362
        /*!
363
         *    Construct a split iterator to iterate through the specified collection
364
         */
365
        template<typename RangeT, typename FinderT>
366
        inline split_iterator< 
367
            BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
368
        make_split_iterator(
369
            RangeT& Collection,
370
            FinderT Finder)
371
        {
372
            return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
373
                Collection, Finder);
374
        }
375
376
377
    } // namespace algorithm
378
379
    // pull names to the boost namespace
380
    using algorithm::find_iterator;
381
    using algorithm::make_find_iterator;
382
    using algorithm::split_iterator;
383
    using algorithm::make_split_iterator;
384
385
} // namespace boost
386
387
388
#endif  // BOOST_STRING_FIND_ITERATOR_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/finder.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library finder.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2006.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FINDER_HPP
12
#define BOOST_STRING_FINDER_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
16
#include <boost/range/iterator_range_core.hpp>
17
#include <boost/range/begin.hpp>
18
#include <boost/range/end.hpp>
19
#include <boost/range/iterator.hpp>
20
#include <boost/range/const_iterator.hpp>
21
22
#include <boost/algorithm/string/constants.hpp>
23
#include <boost/algorithm/string/detail/finder.hpp>
24
#include <boost/algorithm/string/compare.hpp>
25
26
/*! \file
27
    Defines Finder generators. Finder object is a functor which is able to 
28
    find a substring matching a specific criteria in the input.
29
    Finders are used as a pluggable components for replace, find 
30
    and split facilities. This header contains generator functions 
31
    for finders provided in this library.
32
*/
33
34
namespace boost {
35
    namespace algorithm {
36
37
//  Finder generators ------------------------------------------//
38
        
39
        //! "First" finder 
40
        /*!
41
            Construct the \c first_finder. The finder searches for the first
42
            occurrence of the string in a given input.
43
            The result is given as an \c iterator_range delimiting the match.
44
45
            \param Search A substring to be searched for.
46
            \return An instance of the \c first_finder object
47
        */
48
        template<typename RangeT>
49
        inline detail::first_finderF<
50
            BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
51
            is_equal>
52
        first_finder( const RangeT& Search )
53
15
        {
54
15
            return 
55
15
                detail::first_finderF<
56
15
                    BOOST_STRING_TYPENAME 
57
15
                        range_const_iterator<RangeT>::type,
58
15
                        is_equal>( ::boost::as_literal(Search), is_equal() ) ;
59
15
        }
60
61
        //! "First" finder
62
        /*!
63
            \overload
64
        */
65
        template<typename RangeT,typename PredicateT>
66
        inline detail::first_finderF<
67
            BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
68
            PredicateT>
69
        first_finder( 
70
            const RangeT& Search, PredicateT Comp )
71
        {
72
            return 
73
                detail::first_finderF<
74
                    BOOST_STRING_TYPENAME 
75
                        range_const_iterator<RangeT>::type,
76
                    PredicateT>( ::boost::as_literal(Search), Comp );
77
        }
78
79
        //! "Last" finder
80
        /*!
81
            Construct the \c last_finder. The finder searches for the last
82
            occurrence of the string in a given input.
83
            The result is given as an \c iterator_range delimiting the match.
84
85
            \param Search A substring to be searched for.
86
            \return An instance of the \c last_finder object
87
        */
88
        template<typename RangeT>
89
        inline detail::last_finderF<
90
            BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
91
            is_equal>
92
        last_finder( const RangeT& Search )
93
        {
94
            return 
95
                detail::last_finderF<
96
                    BOOST_STRING_TYPENAME 
97
                        range_const_iterator<RangeT>::type,
98
                    is_equal>( ::boost::as_literal(Search), is_equal() );
99
        }
100
        //! "Last" finder
101
        /*!
102
            \overload
103
        */
104
        template<typename RangeT, typename PredicateT>
105
        inline detail::last_finderF<
106
            BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
107
            PredicateT>
108
        last_finder( const RangeT& Search, PredicateT Comp )
109
        {
110
            return 
111
                detail::last_finderF<
112
                    BOOST_STRING_TYPENAME 
113
                        range_const_iterator<RangeT>::type,
114
                    PredicateT>( ::boost::as_literal(Search), Comp ) ;
115
        }
116
117
        //! "Nth" finder
118
        /*!
119
            Construct the \c nth_finder. The finder searches for the n-th (zero-indexed)
120
            occurrence of the string in a given input.
121
            The result is given as an \c iterator_range delimiting the match.
122
123
            \param Search A substring to be searched for.
124
            \param Nth An index of the match to be find
125
            \return An instance of the \c nth_finder object
126
        */
127
        template<typename RangeT>
128
        inline detail::nth_finderF<
129
            BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
130
            is_equal>
131
        nth_finder( 
132
            const RangeT& Search, 
133
            int Nth)
134
        {
135
            return 
136
                detail::nth_finderF<
137
                    BOOST_STRING_TYPENAME 
138
                        range_const_iterator<RangeT>::type,
139
                    is_equal>( ::boost::as_literal(Search), Nth, is_equal() ) ;
140
        }
141
        //! "Nth" finder
142
        /*!
143
            \overload
144
        */
145
        template<typename RangeT, typename PredicateT>
146
        inline detail::nth_finderF<
147
            BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
148
            PredicateT>
149
        nth_finder( 
150
            const RangeT& Search, 
151
            int Nth, 
152
            PredicateT Comp )
153
        {
154
            return 
155
                detail::nth_finderF<
156
                    BOOST_STRING_TYPENAME 
157
                        range_const_iterator<RangeT>::type,
158
                    PredicateT>( ::boost::as_literal(Search), Nth, Comp );
159
        }
160
161
        //! "Head" finder
162
        /*!
163
            Construct the \c head_finder. The finder returns a head of a given
164
            input. The head is a prefix of a string up to n elements in
165
            size. If an input has less then n elements, whole input is 
166
            considered a head.
167
            The result is given as an \c iterator_range delimiting the match.
168
169
            \param N The size of the head
170
            \return An instance of the \c head_finder object
171
        */
172
        inline detail::head_finderF
173
        head_finder( int N )
174
0
        {
175
0
            return detail::head_finderF(N);
176
0
        }
177
        
178
        //! "Tail" finder
179
        /*!
180
            Construct the \c tail_finder. The finder returns a tail of a given
181
            input. The tail is a suffix of a string up to n elements in
182
            size. If an input has less then n elements, whole input is 
183
            considered a head.
184
            The result is given as an \c iterator_range delimiting the match.
185
186
            \param N The size of the head
187
            \return An instance of the \c tail_finder object
188
        */
189
        inline detail::tail_finderF
190
        tail_finder( int N )
191
0
        {
192
0
            return detail::tail_finderF(N);
193
0
        }
194
195
        //! "Token" finder
196
        /*!
197
            Construct the \c token_finder. The finder searches for a token 
198
            specified by a predicate. It is similar to std::find_if 
199
            algorithm, with an exception that it return a range of
200
            instead of a single iterator.
201
202
            If "compress token mode" is enabled, adjacent matching tokens are 
203
            concatenated into one match. Thus the finder can be used to 
204
            search for continuous segments of characters satisfying the 
205
            given predicate.
206
207
            The result is given as an \c iterator_range delimiting the match.
208
209
            \param Pred An element selection predicate
210
            \param eCompress Compress flag
211
            \return An instance of the \c token_finder object
212
        */
213
        template< typename PredicateT >
214
        inline detail::token_finderF<PredicateT>
215
        token_finder( 
216
            PredicateT Pred, 
217
            token_compress_mode_type eCompress=token_compress_off )
218
6
        {
219
6
            return detail::token_finderF<PredicateT>( Pred, eCompress );
220
6
        }
221
222
        //! "Range" finder
223
        /*!
224
            Construct the \c range_finder. The finder does not perform 
225
            any operation. It simply returns the given range for 
226
            any input. 
227
228
            \param Begin Beginning of the range
229
            \param End End of the range
230
            \return An instance of the \c range_finger object
231
        */
232
        template< typename ForwardIteratorT >
233
        inline detail::range_finderF<ForwardIteratorT>
234
        range_finder(
235
            ForwardIteratorT Begin,
236
            ForwardIteratorT End )
237
        {
238
            return detail::range_finderF<ForwardIteratorT>( Begin, End );
239
        }
240
241
        //! "Range" finder
242
        /*!       
243
            \overload
244
        */
245
        template< typename ForwardIteratorT >
246
        inline detail::range_finderF<ForwardIteratorT>
247
        range_finder( iterator_range<ForwardIteratorT> Range )
248
        {
249
            return detail::range_finderF<ForwardIteratorT>( Range );
250
        }
251
252
    } // namespace algorithm
253
254
    // pull the names to the boost namespace
255
    using algorithm::first_finder;
256
    using algorithm::last_finder;
257
    using algorithm::nth_finder;
258
    using algorithm::head_finder;
259
    using algorithm::tail_finder;
260
    using algorithm::token_finder;
261
    using algorithm::range_finder;
262
263
} // namespace boost
264
265
266
#endif  // BOOST_STRING_FINDER_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/formatter.hpp
Line
Count
Source
1
//  Boost string_algo library formatter.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_FORMATTER_HPP
12
#define BOOST_STRING_FORMATTER_HPP
13
14
#include <boost/range/value_type.hpp>
15
#include <boost/range/iterator_range_core.hpp>
16
#include <boost/range/as_literal.hpp>
17
18
#include <boost/algorithm/string/detail/formatter.hpp>
19
20
/*! \file
21
    Defines Formatter generators. Formatter is a functor which formats
22
    a string according to given parameters. A Formatter works
23
    in conjunction with a Finder. A Finder can provide additional information
24
    for a specific Formatter. An example of such a cooperation is regex_finder
25
    and regex_formatter.
26
27
    Formatters are used as pluggable components for replace facilities. 
28
    This header contains generator functions for the Formatters provided in this library.
29
*/
30
31
namespace boost {
32
    namespace algorithm {
33
34
// generic formatters  ---------------------------------------------------------------//
35
36
        //! Constant formatter
37
        /*!
38
            Constructs a \c const_formatter. Const formatter always returns
39
            the same value, regardless of the parameter.
40
41
            \param Format A predefined value used as a result for formatting
42
            \return An instance of the \c const_formatter object.
43
        */
44
        template<typename RangeT>
45
        inline detail::const_formatF<
46
            iterator_range<
47
                BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >
48
        const_formatter(const RangeT& Format)
49
15
        {
50
15
            return detail::const_formatF<
51
15
                iterator_range<
52
15
                    BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >(::boost::as_literal(Format));
53
15
        }
54
55
        //! Identity formatter
56
        /*!
57
            Constructs an \c identity_formatter. Identity formatter always returns
58
            the parameter.
59
60
            \return An instance of the \c identity_formatter object.
61
        */
62
        template<typename RangeT>
63
        inline detail::identity_formatF<
64
            iterator_range<
65
                BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >
66
        identity_formatter()
67
        {
68
            return detail::identity_formatF<
69
                iterator_range<
70
                    BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >();
71
        }
72
73
        //! Empty formatter
74
        /*!
75
            Constructs an \c empty_formatter. Empty formatter always returns an empty
76
            sequence. 
77
78
            \param Input container used to select a correct value_type for the
79
                         resulting empty_container<>.
80
            \return An instance of the \c empty_formatter object.
81
        */
82
        template<typename RangeT>
83
        inline detail::empty_formatF< 
84
            BOOST_STRING_TYPENAME range_value<RangeT>::type>
85
        empty_formatter(const RangeT&)
86
        {
87
            return detail::empty_formatF<
88
                BOOST_STRING_TYPENAME range_value<RangeT>::type>();
89
        }
90
91
        //! Empty formatter
92
        /*!
93
            Constructs a \c dissect_formatter. Dissect formatter uses a specified finder
94
            to extract a portion of the formatted sequence. The first finder's match is returned 
95
            as a result
96
97
            \param Finder a finder used to select a portion of the formatted sequence
98
            \return An instance of the \c dissect_formatter object.
99
        */
100
        template<typename FinderT>
101
        inline detail::dissect_formatF< FinderT >
102
        dissect_formatter(const FinderT& Finder)
103
        {
104
            return detail::dissect_formatF<FinderT>(Finder);
105
        }
106
107
108
    } // namespace algorithm
109
110
    // pull the names to the boost namespace
111
    using algorithm::const_formatter;
112
    using algorithm::identity_formatter;
113
    using algorithm::empty_formatter;
114
    using algorithm::dissect_formatter;
115
116
} // namespace boost
117
118
119
#endif  // BOOST_FORMATTER_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/iter_find.hpp
Line
Count
Source
1
//  Boost string_algo library iter_find.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_ITER_FIND_HPP
12
#define BOOST_STRING_ITER_FIND_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
#include <algorithm>
16
#include <iterator>
17
#include <boost/iterator/transform_iterator.hpp>
18
19
#include <boost/range/iterator_range_core.hpp>
20
#include <boost/range/begin.hpp>
21
#include <boost/range/end.hpp>
22
#include <boost/range/iterator.hpp>
23
#include <boost/range/value_type.hpp>
24
#include <boost/range/as_literal.hpp>
25
26
#include <boost/algorithm/string/concept.hpp>
27
#include <boost/algorithm/string/find_iterator.hpp>
28
#include <boost/algorithm/string/detail/util.hpp>
29
30
/*! \file
31
    Defines generic split algorithms. Split algorithms can be 
32
    used to divide a sequence into several part according 
33
    to a given criteria. Result is given as a 'container 
34
    of containers' where elements are copies or references 
35
    to extracted parts.
36
37
    There are two algorithms provided. One iterates over matching
38
    substrings, the other one over the gaps between these matches.
39
*/
40
41
namespace boost {
42
    namespace algorithm {
43
44
//  iterate find ---------------------------------------------------//
45
46
        //! Iter find algorithm
47
        /*!
48
            This algorithm executes a given finder in iteration on the input,
49
            until the end of input is reached, or no match is found.
50
            Iteration is done using built-in find_iterator, so the real 
51
            searching is performed only when needed.
52
            In each iteration new match is found and added to the result.
53
54
            \param Result A 'container container' to contain the result of search.
55
                Both outer and inner container must have constructor taking a pair
56
                of iterators as an argument.
57
                Typical type of the result is 
58
                    \c std::vector<boost::iterator_range<iterator>>
59
                (each element of such a vector will container a range delimiting 
60
                a match).
61
            \param Input A container which will be searched.
62
            \param Finder A Finder object used for searching
63
            \return A reference to the result
64
65
            \note Prior content of the result will be overwritten.
66
        */
67
        template< 
68
            typename SequenceSequenceT,
69
            typename RangeT,
70
            typename FinderT >
71
        inline SequenceSequenceT&
72
        iter_find(
73
            SequenceSequenceT& Result,
74
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
75
            RangeT&& Input,
76
#else
77
            RangeT& Input,
78
#endif
79
            FinderT Finder )
80
        {
81
            BOOST_CONCEPT_ASSERT((
82
                FinderConcept<
83
                    FinderT,
84
                    BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
85
                ));
86
87
            iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
88
89
            typedef BOOST_STRING_TYPENAME 
90
                range_iterator<RangeT>::type input_iterator_type;
91
            typedef find_iterator<input_iterator_type> find_iterator_type;
92
            typedef detail::copy_iterator_rangeF<
93
                BOOST_STRING_TYPENAME 
94
                    range_value<SequenceSequenceT>::type,
95
                input_iterator_type> copy_range_type;
96
            
97
            input_iterator_type InputEnd=::boost::end(lit_input);
98
99
            typedef transform_iterator<copy_range_type, find_iterator_type>
100
                transform_iter_type;
101
    
102
            transform_iter_type itBegin=
103
                ::boost::make_transform_iterator( 
104
                    find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
105
                    copy_range_type());
106
            
107
            transform_iter_type itEnd=
108
                ::boost::make_transform_iterator( 
109
                    find_iterator_type(),
110
                    copy_range_type());
111
112
            SequenceSequenceT Tmp(itBegin, itEnd);
113
                        
114
            Result.swap(Tmp);
115
            return Result;
116
        }
117
118
//  iterate split ---------------------------------------------------//
119
120
        //! Split find algorithm
121
        /*!
122
            This algorithm executes a given finder in iteration on the input,
123
            until the end of input is reached, or no match is found.
124
            Iteration is done using built-in find_iterator, so the real 
125
            searching is performed only when needed.
126
            Each match is used as a separator of segments. These segments are then
127
            returned in the result.
128
129
            \param Result A 'container container' to contain the result of search.
130
                Both outer and inner container must have constructor taking a pair
131
                of iterators as an argument.
132
                Typical type of the result is 
133
                    \c std::vector<boost::iterator_range<iterator>>
134
                (each element of such a vector will container a range delimiting 
135
                a match).
136
            \param Input A container which will be searched.
137
            \param Finder A finder object used for searching
138
            \return A reference to the result
139
140
            \note Prior content of the result will be overwritten.
141
        */
142
        template< 
143
            typename SequenceSequenceT,
144
            typename RangeT,
145
            typename FinderT >
146
        inline SequenceSequenceT&
147
        iter_split(
148
            SequenceSequenceT& Result,
149
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
150
            RangeT&& Input,
151
#else
152
            RangeT& Input,
153
#endif
154
            FinderT Finder )
155
6
        {
156
6
            BOOST_CONCEPT_ASSERT((
157
6
                FinderConcept<FinderT,
158
6
                BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
159
6
                ));
160
161
6
            iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
162
163
6
            typedef BOOST_STRING_TYPENAME 
164
6
                range_iterator<RangeT>::type input_iterator_type;
165
6
            typedef split_iterator<input_iterator_type> find_iterator_type;
166
6
            typedef detail::copy_iterator_rangeF<
167
6
                BOOST_STRING_TYPENAME 
168
6
                    range_value<SequenceSequenceT>::type,
169
6
                input_iterator_type> copy_range_type;
170
            
171
6
            input_iterator_type InputEnd=::boost::end(lit_input);
172
173
6
            typedef transform_iterator<copy_range_type, find_iterator_type>
174
6
                transform_iter_type;
175
    
176
6
            transform_iter_type itBegin=
177
6
                ::boost::make_transform_iterator( 
178
6
                    find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
179
6
                    copy_range_type() );
180
181
6
            transform_iter_type itEnd=
182
6
                ::boost::make_transform_iterator( 
183
6
                    find_iterator_type(),
184
6
                    copy_range_type() );
185
            
186
6
            SequenceSequenceT Tmp(itBegin, itEnd);
187
188
6
            Result.swap(Tmp);
189
6
            return Result;
190
6
        }
191
192
    } // namespace algorithm
193
194
    // pull names to the boost namespace
195
    using algorithm::iter_find;
196
    using algorithm::iter_split;
197
198
} // namespace boost
199
200
201
#endif  // BOOST_STRING_ITER_FIND_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/predicate.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Boost string_algo library predicate.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2003.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_PREDICATE_HPP
12
#define BOOST_STRING_PREDICATE_HPP
13
14
#include <iterator>
15
#include <boost/algorithm/string/config.hpp>
16
#include <boost/range/begin.hpp>
17
#include <boost/range/end.hpp>
18
#include <boost/range/iterator.hpp>
19
#include <boost/range/const_iterator.hpp>
20
#include <boost/range/as_literal.hpp>
21
#include <boost/range/iterator_range_core.hpp>
22
23
#include <boost/algorithm/string/compare.hpp>
24
#include <boost/algorithm/string/find.hpp>
25
#include <boost/algorithm/string/detail/predicate.hpp>
26
27
/*! \file boost/algorithm/string/predicate.hpp
28
    Defines string-related predicates. 
29
    The predicates determine whether a substring is contained in the input string 
30
    under various conditions: a string starts with the substring, ends with the 
31
    substring, simply contains the substring or if both strings are equal.
32
    Additionaly the algorithm \c all() checks all elements of a container to satisfy a 
33
    condition.
34
35
    All predicates provide the strong exception guarantee.
36
*/
37
38
namespace boost {
39
    namespace algorithm {
40
41
//  starts_with predicate  -----------------------------------------------//
42
43
        //! 'Starts with' predicate
44
        /*!
45
            This predicate holds when the test string is a prefix of the Input.
46
            In other words, if the input starts with the test.
47
            When the optional predicate is specified, it is used for character-wise
48
            comparison.
49
50
            \param Input An input sequence
51
            \param Test A test sequence
52
            \param Comp An element comparison predicate
53
            \return The result of the test
54
55
              \note This function provides the strong exception-safety guarantee
56
        */
57
        template<typename Range1T, typename Range2T, typename PredicateT>
58
            inline bool starts_with( 
59
            const Range1T& Input, 
60
            const Range2T& Test,
61
            PredicateT Comp)
62
        {
63
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
64
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
65
66
            typedef BOOST_STRING_TYPENAME 
67
                range_const_iterator<Range1T>::type Iterator1T;
68
            typedef BOOST_STRING_TYPENAME 
69
                range_const_iterator<Range2T>::type Iterator2T;
70
71
            Iterator1T InputEnd=::boost::end(lit_input);
72
            Iterator2T TestEnd=::boost::end(lit_test);
73
74
            Iterator1T it=::boost::begin(lit_input);
75
            Iterator2T pit=::boost::begin(lit_test);
76
            for(;
77
                it!=InputEnd && pit!=TestEnd;
78
                ++it,++pit)
79
            {
80
                if( !(Comp(*it,*pit)) )
81
                    return false;
82
            }
83
84
            return pit==TestEnd;
85
        }
86
87
        //! 'Starts with' predicate
88
        /*!
89
            \overload
90
        */
91
        template<typename Range1T, typename Range2T>
92
        inline bool starts_with( 
93
            const Range1T& Input, 
94
            const Range2T& Test)
95
        {
96
            return ::boost::algorithm::starts_with(Input, Test, is_equal());
97
        }
98
99
        //! 'Starts with' predicate ( case insensitive )
100
        /*!
101
            This predicate holds when the test string is a prefix of the Input.
102
            In other words, if the input starts with the test.
103
            Elements are compared case insensitively.
104
105
            \param Input An input sequence
106
            \param Test A test sequence
107
            \param Loc A locale used for case insensitive comparison
108
            \return The result of the test
109
110
            \note This function provides the strong exception-safety guarantee
111
        */
112
        template<typename Range1T, typename Range2T>
113
        inline bool istarts_with( 
114
            const Range1T& Input, 
115
            const Range2T& Test,
116
            const std::locale& Loc=std::locale())
117
        {
118
            return ::boost::algorithm::starts_with(Input, Test, is_iequal(Loc));
119
        }
120
121
122
//  ends_with predicate  -----------------------------------------------//
123
124
        //! 'Ends with' predicate
125
        /*!
126
            This predicate holds when the test string is a suffix of the Input.
127
            In other words, if the input ends with the test.
128
            When the optional predicate is specified, it is used for character-wise
129
            comparison.
130
131
132
            \param Input An input sequence
133
            \param Test A test sequence
134
            \param Comp An element comparison predicate
135
            \return The result of the test
136
137
              \note This function provides the strong exception-safety guarantee
138
        */
139
        template<typename Range1T, typename Range2T, typename PredicateT>
140
        inline bool ends_with( 
141
            const Range1T& Input, 
142
            const Range2T& Test,
143
            PredicateT Comp)
144
        {
145
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
146
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
147
148
            typedef BOOST_STRING_TYPENAME
149
                range_const_iterator<Range1T>::type Iterator1T;
150
            typedef BOOST_STRING_TYPENAME
151
                std::iterator_traits<Iterator1T>::iterator_category category;
152
153
            return detail::
154
                ends_with_iter_select( 
155
                    ::boost::begin(lit_input), 
156
                    ::boost::end(lit_input), 
157
                    ::boost::begin(lit_test), 
158
                    ::boost::end(lit_test), 
159
                    Comp,
160
                    category());
161
        }
162
163
164
        //! 'Ends with' predicate
165
        /*!
166
            \overload
167
        */
168
        template<typename Range1T, typename Range2T>
169
        inline bool ends_with( 
170
            const Range1T& Input, 
171
            const Range2T& Test)
172
        {
173
            return ::boost::algorithm::ends_with(Input, Test, is_equal());
174
        }
175
176
        //! 'Ends with' predicate ( case insensitive )
177
        /*!
178
            This predicate holds when the test container is a suffix of the Input.
179
            In other words, if the input ends with the test.
180
            Elements are compared case insensitively.
181
182
            \param Input An input sequence
183
            \param Test A test sequence
184
            \param Loc A locale used for case insensitive comparison
185
            \return The result of the test
186
187
            \note This function provides the strong exception-safety guarantee
188
        */
189
        template<typename Range1T, typename Range2T>
190
        inline bool iends_with( 
191
            const Range1T& Input, 
192
            const Range2T& Test,
193
            const std::locale& Loc=std::locale())
194
        {
195
            return ::boost::algorithm::ends_with(Input, Test, is_iequal(Loc));
196
        }
197
198
//  contains predicate  -----------------------------------------------//
199
200
        //! 'Contains' predicate
201
        /*!
202
            This predicate holds when the test container is contained in the Input.
203
            When the optional predicate is specified, it is used for character-wise
204
            comparison.
205
206
            \param Input An input sequence
207
            \param Test A test sequence
208
            \param Comp An element comparison predicate
209
            \return The result of the test
210
211
               \note This function provides the strong exception-safety guarantee
212
        */
213
        template<typename Range1T, typename Range2T, typename PredicateT>
214
        inline bool contains( 
215
            const Range1T& Input, 
216
            const Range2T& Test,
217
            PredicateT Comp)
218
        {
219
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
220
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
221
222
            if (::boost::empty(lit_test))
223
            {
224
                // Empty range is contained always
225
                return true;
226
            }
227
            
228
            // Use the temporary variable to make VACPP happy
229
            bool bResult=(::boost::algorithm::first_finder(lit_test,Comp)(::boost::begin(lit_input), ::boost::end(lit_input)));
230
            return bResult;
231
        }
232
233
        //! 'Contains' predicate
234
        /*!
235
            \overload
236
        */
237
        template<typename Range1T, typename Range2T>
238
        inline bool contains( 
239
            const Range1T& Input, 
240
            const Range2T& Test)
241
        {
242
            return ::boost::algorithm::contains(Input, Test, is_equal());
243
        }
244
245
        //! 'Contains' predicate ( case insensitive )
246
        /*!
247
            This predicate holds when the test container is contained in the Input.
248
            Elements are compared case insensitively.
249
250
            \param Input An input sequence
251
            \param Test A test sequence
252
            \param Loc A locale used for case insensitive comparison
253
            \return The result of the test
254
255
            \note This function provides the strong exception-safety guarantee
256
        */
257
        template<typename Range1T, typename Range2T>
258
        inline bool icontains( 
259
            const Range1T& Input, 
260
            const Range2T& Test, 
261
            const std::locale& Loc=std::locale())
262
        {
263
            return ::boost::algorithm::contains(Input, Test, is_iequal(Loc));
264
        }
265
266
//  equals predicate  -----------------------------------------------//
267
268
        //! 'Equals' predicate
269
        /*!
270
            This predicate holds when the test container is equal to the
271
            input container i.e. all elements in both containers are same.
272
            When the optional predicate is specified, it is used for character-wise
273
            comparison.
274
275
            \param Input An input sequence
276
            \param Test A test sequence
277
            \param Comp An element comparison predicate
278
            \return The result of the test
279
280
            \note This is a two-way version of \c std::equal algorithm
281
282
            \note This function provides the strong exception-safety guarantee
283
        */
284
        template<typename Range1T, typename Range2T, typename PredicateT>
285
        inline bool equals( 
286
            const Range1T& Input, 
287
            const Range2T& Test,
288
            PredicateT Comp)
289
        {
290
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
291
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
292
293
            typedef BOOST_STRING_TYPENAME 
294
                range_const_iterator<Range1T>::type Iterator1T;
295
            typedef BOOST_STRING_TYPENAME 
296
                range_const_iterator<Range2T>::type Iterator2T;
297
                
298
            Iterator1T InputEnd=::boost::end(lit_input);
299
            Iterator2T TestEnd=::boost::end(lit_test);
300
301
            Iterator1T it=::boost::begin(lit_input);
302
            Iterator2T pit=::boost::begin(lit_test);
303
            for(;
304
                it!=InputEnd && pit!=TestEnd;
305
                ++it,++pit)
306
            {
307
                if( !(Comp(*it,*pit)) )
308
                    return false;
309
            }
310
311
            return  (pit==TestEnd) && (it==InputEnd);
312
        }
313
314
        //! 'Equals' predicate
315
        /*!
316
            \overload
317
        */
318
        template<typename Range1T, typename Range2T>
319
        inline bool equals( 
320
            const Range1T& Input, 
321
            const Range2T& Test)
322
        {
323
            return ::boost::algorithm::equals(Input, Test, is_equal());
324
        }
325
326
        //! 'Equals' predicate ( case insensitive )
327
        /*!
328
            This predicate holds when the test container is equal to the
329
            input container i.e. all elements in both containers are same.
330
            Elements are compared case insensitively.
331
332
            \param Input An input sequence
333
            \param Test A test sequence
334
            \param Loc A locale used for case insensitive comparison
335
            \return The result of the test
336
337
            \note This is a two-way version of \c std::equal algorithm
338
339
            \note This function provides the strong exception-safety guarantee
340
        */
341
        template<typename Range1T, typename Range2T>
342
        inline bool iequals( 
343
            const Range1T& Input, 
344
            const Range2T& Test,
345
            const std::locale& Loc=std::locale())
346
        {
347
            return ::boost::algorithm::equals(Input, Test, is_iequal(Loc));
348
        }
349
350
// lexicographical_compare predicate -----------------------------//
351
352
        //! Lexicographical compare predicate
353
        /*!
354
             This predicate is an overload of std::lexicographical_compare
355
             for range arguments
356
357
             It check whether the first argument is lexicographically less
358
             then the second one.
359
360
             If the optional predicate is specified, it is used for character-wise
361
             comparison
362
363
             \param Arg1 First argument 
364
             \param Arg2 Second argument
365
             \param Pred Comparison predicate
366
             \return The result of the test
367
368
             \note This function provides the strong exception-safety guarantee
369
         */
370
        template<typename Range1T, typename Range2T, typename PredicateT>
371
        inline bool lexicographical_compare(
372
            const Range1T& Arg1,
373
            const Range2T& Arg2,
374
            PredicateT Pred)
375
        {
376
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_arg1(::boost::as_literal(Arg1));
377
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_arg2(::boost::as_literal(Arg2));
378
379
            return std::lexicographical_compare(
380
                ::boost::begin(lit_arg1),
381
                ::boost::end(lit_arg1),
382
                ::boost::begin(lit_arg2),
383
                ::boost::end(lit_arg2),
384
                Pred);
385
        }
386
387
        //! Lexicographical compare predicate
388
        /*!
389
            \overload
390
         */
391
        template<typename Range1T, typename Range2T>
392
            inline bool lexicographical_compare(
393
            const Range1T& Arg1,
394
            const Range2T& Arg2)
395
        {
396
            return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_less());
397
        }
398
399
        //! Lexicographical compare predicate (case-insensitive)
400
        /*!
401
            This predicate is an overload of std::lexicographical_compare
402
            for range arguments.
403
            It check whether the first argument is lexicographically less
404
            then the second one.
405
            Elements are compared case insensitively
406
407
408
             \param Arg1 First argument 
409
             \param Arg2 Second argument
410
             \param Loc A locale used for case insensitive comparison
411
             \return The result of the test
412
413
             \note This function provides the strong exception-safety guarantee
414
         */
415
        template<typename Range1T, typename Range2T>
416
        inline bool ilexicographical_compare(
417
            const Range1T& Arg1,
418
            const Range2T& Arg2,
419
            const std::locale& Loc=std::locale())
420
        {
421
            return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_iless(Loc));
422
        }
423
        
424
425
//  all predicate  -----------------------------------------------//
426
427
        //! 'All' predicate
428
        /*!
429
            This predicate holds it all its elements satisfy a given 
430
            condition, represented by the predicate.
431
            
432
            \param Input An input sequence
433
            \param Pred A predicate
434
            \return The result of the test
435
436
            \note This function provides the strong exception-safety guarantee
437
        */
438
        template<typename RangeT, typename PredicateT>
439
        inline bool all( 
440
            const RangeT& Input, 
441
            PredicateT Pred)
442
15
        {
443
15
            iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
444
445
15
            typedef BOOST_STRING_TYPENAME 
446
15
                range_const_iterator<RangeT>::type Iterator1T;
447
448
15
            Iterator1T InputEnd=::boost::end(lit_input);
449
39
            for( Iterator1T It=::boost::begin(lit_input); It!=InputEnd; ++It)
450
24
            {
451
24
                if (!Pred(*It))
452
0
                    return false;
453
24
            }
454
            
455
15
            return true;
456
15
        }
457
458
    } // namespace algorithm
459
460
    // pull names to the boost namespace
461
    using algorithm::starts_with;
462
    using algorithm::istarts_with;
463
    using algorithm::ends_with;
464
    using algorithm::iends_with;
465
    using algorithm::contains;
466
    using algorithm::icontains;
467
    using algorithm::equals;
468
    using algorithm::iequals;
469
    using algorithm::all;
470
    using algorithm::lexicographical_compare;
471
    using algorithm::ilexicographical_compare;
472
473
} // namespace boost
474
475
476
#endif  // BOOST_STRING_PREDICATE_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/replace.hpp
Line
Count
Source
1
//  Boost string_algo library replace.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2006.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_REPLACE_HPP
12
#define BOOST_STRING_REPLACE_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
16
#include <boost/range/iterator_range_core.hpp>
17
#include <boost/range/begin.hpp>
18
#include <boost/range/end.hpp>
19
#include <boost/range/iterator.hpp>
20
#include <boost/range/const_iterator.hpp>
21
22
#include <boost/algorithm/string/find_format.hpp>
23
#include <boost/algorithm/string/finder.hpp>
24
#include <boost/algorithm/string/formatter.hpp>
25
#include <boost/algorithm/string/compare.hpp>
26
27
/*! \file
28
    Defines various replace algorithms. Each algorithm replaces
29
    part(s) of the input according to set of searching and replace criteria.
30
*/
31
32
namespace boost {
33
    namespace algorithm {
34
35
//  replace_range --------------------------------------------------------------------//
36
37
        //! Replace range algorithm
38
        /*!
39
            Replace the given range in the input string.
40
            The result is a modified copy of the input. It is returned as a sequence 
41
            or copied to the output iterator.
42
            
43
            \param Output An output iterator to which the result will be copied
44
            \param Input An input string
45
            \param SearchRange A range in the input to be substituted
46
            \param Format A substitute string
47
            \return An output iterator pointing just after the last inserted character or
48
                a modified copy of the input
49
50
              \note The second variant of this function provides the strong exception-safety guarantee
51
        */
52
        template<
53
            typename OutputIteratorT,
54
            typename Range1T, 
55
            typename Range2T>
56
        inline OutputIteratorT replace_range_copy(
57
            OutputIteratorT Output,
58
            const Range1T& Input,
59
            const iterator_range<
60
                BOOST_STRING_TYPENAME 
61
                    range_const_iterator<Range1T>::type>& SearchRange,
62
            const Range2T& Format)
63
        {
64
            return ::boost::algorithm::find_format_copy(
65
                Output,
66
                Input,
67
                ::boost::algorithm::range_finder(SearchRange),
68
                ::boost::algorithm::const_formatter(Format));
69
        }
70
71
        //! Replace range algorithm
72
        /*!
73
            \overload
74
        */
75
        template<typename SequenceT, typename RangeT>
76
        inline SequenceT replace_range_copy( 
77
            const SequenceT& Input,
78
            const iterator_range<
79
                BOOST_STRING_TYPENAME 
80
                    range_const_iterator<SequenceT>::type>& SearchRange,
81
            const RangeT& Format)
82
        {
83
            return ::boost::algorithm::find_format_copy(
84
                Input,
85
                ::boost::algorithm::range_finder(SearchRange),
86
                ::boost::algorithm::const_formatter(Format));
87
        }
88
89
        //! Replace range algorithm
90
        /*!
91
            Replace the given range in the input string. 
92
            The input sequence is modified in-place.
93
94
            \param Input An input string
95
            \param SearchRange A range in the input to be substituted
96
            \param Format A substitute string
97
        */
98
        template<typename SequenceT, typename RangeT>
99
        inline void replace_range( 
100
            SequenceT& Input,
101
            const iterator_range<
102
                BOOST_STRING_TYPENAME 
103
                    range_iterator<SequenceT>::type>& SearchRange,
104
            const RangeT& Format)
105
        {
106
            ::boost::algorithm::find_format(
107
                Input,
108
                ::boost::algorithm::range_finder(SearchRange),
109
                ::boost::algorithm::const_formatter(Format));
110
        }
111
112
//  replace_first --------------------------------------------------------------------//
113
114
        //! Replace first algorithm
115
        /*!
116
            Replace the first match of the search substring in the input 
117
            with the format string. 
118
            The result is a modified copy of the input. It is returned as a sequence 
119
            or copied to the output iterator.
120
            
121
            \param Output An output iterator to which the result will be copied
122
            \param Input An input string
123
            \param Search A substring to be searched for 
124
            \param Format A substitute string
125
            \return An output iterator pointing just after the last inserted character or
126
                    a modified copy of the input
127
128
              \note The second variant of this function provides the strong exception-safety guarantee
129
        */
130
        template<
131
            typename OutputIteratorT,
132
            typename Range1T, 
133
            typename Range2T,
134
            typename Range3T>
135
        inline OutputIteratorT replace_first_copy(
136
            OutputIteratorT Output,
137
            const Range1T& Input,
138
            const Range2T& Search,
139
            const Range3T& Format)
140
        {
141
            return ::boost::algorithm::find_format_copy(
142
                Output,
143
                Input,
144
                ::boost::algorithm::first_finder(Search),
145
                ::boost::algorithm::const_formatter(Format) );
146
        }
147
148
        //! Replace first algorithm
149
        /*!
150
            \overload
151
        */
152
        template<typename SequenceT, typename Range1T, typename Range2T>
153
        inline SequenceT replace_first_copy( 
154
            const SequenceT& Input,
155
            const Range1T& Search,
156
            const Range2T& Format )
157
        {
158
            return ::boost::algorithm::find_format_copy( 
159
                Input,
160
                ::boost::algorithm::first_finder(Search),
161
                ::boost::algorithm::const_formatter(Format) );
162
        }
163
164
        //! Replace first algorithm
165
        /*!
166
            replace the first match of the search substring in the input 
167
            with the format string. The input sequence is modified in-place.
168
169
            \param Input An input string
170
            \param Search A substring to be searched for 
171
            \param Format A substitute string
172
        */
173
        template<typename SequenceT, typename Range1T, typename Range2T>
174
        inline void replace_first( 
175
            SequenceT& Input,
176
            const Range1T& Search,
177
            const Range2T& Format )
178
        {
179
            ::boost::algorithm::find_format( 
180
                Input, 
181
                ::boost::algorithm::first_finder(Search),
182
                ::boost::algorithm::const_formatter(Format) );
183
        }
184
185
//  replace_first ( case insensitive ) ---------------------------------------------//
186
187
        //! Replace first algorithm ( case insensitive )
188
        /*!
189
            Replace the first match of the search substring in the input 
190
            with the format string. 
191
            The result is a modified copy of the input. It is returned as a sequence 
192
            or copied to the output iterator.
193
            Searching is case insensitive.
194
195
            \param Output An output iterator to which the result will be copied
196
            \param Input An input string
197
            \param Search A substring to be searched for 
198
            \param Format A substitute string
199
            \param Loc A locale used for case insensitive comparison
200
            \return An output iterator pointing just after the last inserted character or
201
                a modified copy of the input
202
203
             \note The second variant of this function provides the strong exception-safety guarantee
204
        */
205
        template<
206
            typename OutputIteratorT,
207
            typename Range1T, 
208
            typename Range2T,
209
            typename Range3T>
210
        inline OutputIteratorT ireplace_first_copy(
211
            OutputIteratorT Output,
212
            const Range1T& Input,
213
            const Range2T& Search,
214
            const Range3T& Format,
215
            const std::locale& Loc=std::locale() )
216
        {
217
            return ::boost::algorithm::find_format_copy(
218
                Output,
219
                Input,
220
                ::boost::algorithm::first_finder(Search, is_iequal(Loc)),
221
                ::boost::algorithm::const_formatter(Format) );
222
        }
223
224
        //! Replace first algorithm ( case insensitive )
225
        /*!
226
            \overload
227
        */
228
        template<typename SequenceT, typename Range2T, typename Range1T>
229
        inline SequenceT ireplace_first_copy( 
230
            const SequenceT& Input,
231
            const Range2T& Search,
232
            const Range1T& Format,
233
            const std::locale& Loc=std::locale() )
234
        {
235
            return ::boost::algorithm::find_format_copy( 
236
                Input,
237
                ::boost::algorithm::first_finder(Search, is_iequal(Loc)),
238
                ::boost::algorithm::const_formatter(Format) );
239
        }
240
241
        //! Replace first algorithm ( case insensitive )
242
        /*!
243
            Replace the first match of the search substring in the input 
244
            with the format string. Input sequence is modified in-place.
245
            Searching is case insensitive.
246
247
            \param Input An input string
248
            \param Search A substring to be searched for 
249
            \param Format A substitute string
250
            \param Loc A locale used for case insensitive comparison
251
        */
252
        template<typename SequenceT, typename Range1T, typename Range2T>
253
        inline void ireplace_first( 
254
            SequenceT& Input,
255
            const Range1T& Search,
256
            const Range2T& Format,
257
            const std::locale& Loc=std::locale() )
258
        {
259
            ::boost::algorithm::find_format( 
260
                Input, 
261
                ::boost::algorithm::first_finder(Search, is_iequal(Loc)),
262
                ::boost::algorithm::const_formatter(Format) );
263
        }
264
265
//  replace_last --------------------------------------------------------------------//
266
267
        //! Replace last algorithm
268
        /*!
269
            Replace the last match of the search string in the input 
270
            with the format string. 
271
            The result is a modified copy of the input. It is returned as a sequence 
272
            or copied to the output iterator.
273
274
            \param Output An output iterator to which the result will be copied
275
            \param Input An input string
276
            \param Search A substring to be searched for
277
            \param Format A substitute string
278
            \return An output iterator pointing just after the last inserted character or
279
                    a modified copy of the input            
280
281
              \note The second variant of this function provides the strong exception-safety guarantee
282
        */
283
        template<
284
            typename OutputIteratorT,
285
            typename Range1T, 
286
            typename Range2T,
287
            typename Range3T>
288
        inline OutputIteratorT replace_last_copy(
289
            OutputIteratorT Output,
290
            const Range1T& Input,
291
            const Range2T& Search,
292
            const Range3T& Format )
293
        {
294
            return ::boost::algorithm::find_format_copy(
295
                Output,
296
                Input,
297
                ::boost::algorithm::last_finder(Search),
298
                ::boost::algorithm::const_formatter(Format) );
299
        }
300
301
        //! Replace last algorithm
302
        /*!
303
            \overload
304
        */
305
        template<typename SequenceT, typename Range1T, typename Range2T>
306
        inline SequenceT replace_last_copy( 
307
            const SequenceT& Input,
308
            const Range1T& Search,
309
            const Range2T& Format )
310
        {
311
            return ::boost::algorithm::find_format_copy( 
312
                Input,
313
                ::boost::algorithm::last_finder(Search),
314
                ::boost::algorithm::const_formatter(Format) );
315
        }
316
317
        //! Replace last algorithm
318
        /*!
319
            Replace the last match of the search string in the input 
320
            with the format string. Input sequence is modified in-place.
321
322
            \param Input An input string
323
            \param Search A substring to be searched for 
324
            \param Format A substitute string
325
        */
326
        template<typename SequenceT, typename Range1T, typename Range2T>
327
        inline void replace_last( 
328
            SequenceT& Input,
329
            const Range1T& Search,
330
            const Range2T& Format )
331
        {
332
            ::boost::algorithm::find_format( 
333
                Input, 
334
                ::boost::algorithm::last_finder(Search),
335
                ::boost::algorithm::const_formatter(Format) );
336
        }
337
338
//  replace_last ( case insensitive ) -----------------------------------------------//
339
340
        //! Replace last algorithm ( case insensitive )
341
        /*!
342
            Replace the last match of the search string in the input 
343
            with the format string. 
344
            The result is a modified copy of the input. It is returned as a sequence 
345
            or copied to the output iterator.
346
            Searching is case insensitive.
347
348
            \param Output An output iterator to which the result will be copied
349
            \param Input An input string
350
            \param Search A substring to be searched for 
351
            \param Format A substitute string
352
            \param Loc A locale used for case insensitive comparison
353
            \return An output iterator pointing just after the last inserted character or
354
                    a modified copy of the input  
355
356
            \note The second variant of this function provides the strong exception-safety guarantee
357
        */
358
        template<
359
            typename OutputIteratorT,
360
            typename Range1T, 
361
            typename Range2T,
362
            typename Range3T>
363
        inline OutputIteratorT ireplace_last_copy(
364
            OutputIteratorT Output,
365
            const Range1T& Input,
366
            const Range2T& Search,
367
            const Range3T& Format,
368
            const std::locale& Loc=std::locale() )
369
        {
370
            return ::boost::algorithm::find_format_copy(
371
                Output,
372
                Input,
373
                ::boost::algorithm::last_finder(Search, is_iequal(Loc)),
374
                ::boost::algorithm::const_formatter(Format) );
375
        }
376
377
        //! Replace last algorithm ( case insensitive )
378
        /*!
379
            \overload
380
        */
381
        template<typename SequenceT, typename Range1T, typename Range2T>
382
        inline SequenceT ireplace_last_copy( 
383
            const SequenceT& Input,
384
            const Range1T& Search,
385
            const Range2T& Format,
386
            const std::locale& Loc=std::locale() )
387
        {
388
            return ::boost::algorithm::find_format_copy( 
389
                Input,
390
                ::boost::algorithm::last_finder(Search, is_iequal(Loc)),
391
                ::boost::algorithm::const_formatter(Format) );
392
        }
393
394
        //! Replace last algorithm ( case insensitive )
395
        /*!
396
            Replace the last match of the search string in the input 
397
            with the format string.The input sequence is modified in-place.
398
            Searching is case insensitive.
399
400
            \param Input An input string
401
            \param Search A substring to be searched for 
402
            \param Format A substitute string
403
            \param Loc A locale used for case insensitive comparison
404
        */
405
        template<typename SequenceT, typename Range1T, typename Range2T>
406
        inline void ireplace_last( 
407
            SequenceT& Input,
408
            const Range1T& Search,
409
            const Range2T& Format,
410
            const std::locale& Loc=std::locale() )
411
        {
412
            ::boost::algorithm::find_format( 
413
                Input, 
414
                ::boost::algorithm::last_finder(Search, is_iequal(Loc)),
415
                ::boost::algorithm::const_formatter(Format) );
416
        }
417
418
//  replace_nth --------------------------------------------------------------------//
419
420
        //! Replace nth algorithm
421
        /*!
422
            Replace an Nth (zero-indexed) match of the search string in the input 
423
            with the format string. 
424
            The result is a modified copy of the input. It is returned as a sequence 
425
            or copied to the output iterator.
426
427
            \param Output An output iterator to which the result will be copied
428
            \param Input An input string
429
            \param Search A substring to be searched for 
430
            \param Nth An index of the match to be replaced. The index is 0-based.
431
                For negative N, matches are counted from the end of string.
432
            \param Format A substitute string
433
            \return An output iterator pointing just after the last inserted character or
434
                a modified copy of the input
435
436
            \note The second variant of this function provides the strong exception-safety guarantee
437
        */
438
        template<
439
            typename OutputIteratorT,
440
            typename Range1T, 
441
            typename Range2T,
442
            typename Range3T>
443
        inline OutputIteratorT replace_nth_copy(
444
            OutputIteratorT Output,
445
            const Range1T& Input,
446
            const Range2T& Search,
447
            int Nth,
448
            const Range3T& Format )
449
        {
450
            return ::boost::algorithm::find_format_copy(
451
                Output,
452
                Input,
453
                ::boost::algorithm::nth_finder(Search, Nth),
454
                ::boost::algorithm::const_formatter(Format) );
455
        }
456
457
        //! Replace nth algorithm
458
        /*!
459
            \overload
460
        */
461
        template<typename SequenceT, typename Range1T, typename Range2T>
462
        inline SequenceT replace_nth_copy( 
463
            const SequenceT& Input,
464
            const Range1T& Search,
465
            int Nth,
466
            const Range2T& Format )
467
        {
468
            return ::boost::algorithm::find_format_copy( 
469
                Input,
470
                ::boost::algorithm::nth_finder(Search, Nth),
471
                ::boost::algorithm::const_formatter(Format) );
472
        }
473
474
        //! Replace nth algorithm
475
        /*!
476
            Replace an Nth (zero-indexed) match of the search string in the input 
477
            with the format string. Input sequence is modified in-place.
478
479
            \param Input An input string
480
            \param Search A substring to be searched for 
481
            \param Nth An index of the match to be replaced. The index is 0-based.
482
                For negative N, matches are counted from the end of string.
483
            \param Format A substitute string
484
        */
485
        template<typename SequenceT, typename Range1T, typename Range2T>
486
        inline void replace_nth( 
487
            SequenceT& Input,
488
            const Range1T& Search,
489
            int Nth,
490
            const Range2T& Format )
491
        {
492
            ::boost::algorithm::find_format( 
493
                Input, 
494
                ::boost::algorithm::nth_finder(Search, Nth),
495
                ::boost::algorithm::const_formatter(Format) );
496
        }
497
498
//  replace_nth ( case insensitive ) -----------------------------------------------//
499
        
500
        //! Replace nth algorithm ( case insensitive )
501
        /*!
502
            Replace an Nth (zero-indexed) match of the search string in the input 
503
            with the format string. 
504
            The result is a modified copy of the input. It is returned as a sequence 
505
            or copied to the output iterator.
506
            Searching is case insensitive.
507
508
            \param Output An output iterator to which the result will be copied
509
            \param Input An input string
510
            \param Search A substring to be searched for 
511
            \param Nth An index of the match to be replaced. The index is 0-based.
512
                For negative N, matches are counted from the end of string.
513
            \param Format A substitute string
514
            \param Loc A locale used for case insensitive comparison
515
            \return An output iterator pointing just after the last inserted character or
516
                    a modified copy of the input            
517
518
            \note The second variant of this function provides the strong exception-safety guarantee
519
       */
520
        template<
521
            typename OutputIteratorT,
522
            typename Range1T, 
523
            typename Range2T,
524
            typename Range3T>
525
        inline OutputIteratorT ireplace_nth_copy(
526
            OutputIteratorT Output,
527
            const Range1T& Input,
528
            const Range2T& Search,
529
            int Nth,
530
            const Range3T& Format,
531
            const std::locale& Loc=std::locale() )
532
        {
533
            return ::boost::algorithm::find_format_copy(
534
                Output,
535
                Input,
536
                ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc) ),
537
                ::boost::algorithm::const_formatter(Format) );
538
        }
539
540
        //! Replace nth algorithm ( case insensitive )
541
        /*!
542
            \overload
543
        */
544
        template<typename SequenceT, typename Range1T, typename Range2T>
545
        inline SequenceT ireplace_nth_copy( 
546
            const SequenceT& Input,
547
            const Range1T& Search,
548
            int Nth,
549
            const Range2T& Format,
550
            const std::locale& Loc=std::locale() )
551
        {
552
            return ::boost::algorithm::find_format_copy( 
553
                Input,
554
                ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
555
                ::boost::algorithm::const_formatter(Format) );
556
        }
557
558
        //! Replace nth algorithm ( case insensitive )
559
        /*!
560
            Replace an Nth (zero-indexed) match of the search string in the input 
561
            with the format string. Input sequence is modified in-place.
562
            Searching is case insensitive.
563
564
            \param Input An input string
565
            \param Search A substring to be searched for 
566
            \param Nth An index of the match to be replaced. The index is 0-based.
567
                For negative N, matches are counted from the end of string.
568
            \param Format A substitute string
569
            \param Loc A locale used for case insensitive comparison
570
        */
571
        template<typename SequenceT, typename Range1T, typename Range2T>
572
        inline void ireplace_nth( 
573
            SequenceT& Input,
574
            const Range1T& Search,
575
            int Nth,
576
            const Range2T& Format,
577
            const std::locale& Loc=std::locale() )
578
        {
579
            ::boost::algorithm::find_format( 
580
                Input, 
581
                ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
582
                ::boost::algorithm::const_formatter(Format) );
583
        }
584
585
//  replace_all --------------------------------------------------------------------//
586
587
        //! Replace all algorithm
588
        /*!
589
            Replace all occurrences of the search string in the input 
590
            with the format string. 
591
            The result is a modified copy of the input. It is returned as a sequence 
592
            or copied to the output iterator.
593
594
            \param Output An output iterator to which the result will be copied
595
            \param Input An input string
596
            \param Search A substring to be searched for 
597
            \param Format A substitute string
598
            \return An output iterator pointing just after the last inserted character or
599
                    a modified copy of the input 
600
601
             \note The second variant of this function provides the strong exception-safety guarantee
602
        */
603
        template<
604
            typename OutputIteratorT,
605
            typename Range1T, 
606
            typename Range2T,
607
            typename Range3T>
608
        inline OutputIteratorT replace_all_copy(
609
            OutputIteratorT Output,
610
            const Range1T& Input,
611
            const Range2T& Search,
612
            const Range3T& Format )
613
        {
614
            return ::boost::algorithm::find_format_all_copy(
615
                Output,
616
                Input,
617
                ::boost::algorithm::first_finder(Search),
618
                ::boost::algorithm::const_formatter(Format) );
619
        }
620
621
        //! Replace all algorithm
622
        /*!
623
            \overload
624
        */
625
        template<typename SequenceT, typename Range1T, typename Range2T>
626
        inline SequenceT replace_all_copy( 
627
            const SequenceT& Input,
628
            const Range1T& Search,
629
            const Range2T& Format )
630
        {
631
            return ::boost::algorithm::find_format_all_copy( 
632
                Input,
633
                ::boost::algorithm::first_finder(Search),
634
                ::boost::algorithm::const_formatter(Format) );
635
        }
636
637
        //! Replace all algorithm
638
        /*!
639
            Replace all occurrences of the search string in the input 
640
            with the format string. The input sequence is modified in-place.
641
642
            \param Input An input string
643
            \param Search A substring to be searched for 
644
            \param Format A substitute string
645
        */
646
        template<typename SequenceT, typename Range1T, typename Range2T>
647
        inline void replace_all( 
648
            SequenceT& Input,
649
            const Range1T& Search,
650
            const Range2T& Format )
651
15
        {
652
15
            ::boost::algorithm::find_format_all( 
653
15
                Input, 
654
15
                ::boost::algorithm::first_finder(Search),
655
15
                ::boost::algorithm::const_formatter(Format) );
656
15
        }
657
        
658
//  replace_all ( case insensitive ) -----------------------------------------------//
659
660
        //! Replace all algorithm ( case insensitive )
661
        /*!
662
            Replace all occurrences of the search string in the input 
663
            with the format string. 
664
            The result is a modified copy of the input. It is returned as a sequence 
665
            or copied to the output iterator.
666
            Searching is case insensitive.
667
668
            \param Output An output iterator to which the result will be copied
669
            \param Input An input string
670
            \param Search A substring to be searched for 
671
            \param Format A substitute string
672
            \param Loc A locale used for case insensitive comparison
673
            \return An output iterator pointing just after the last inserted character or
674
                    a modified copy of the input 
675
676
            \note The second variant of this function provides the strong exception-safety guarantee
677
        */
678
        template<
679
            typename OutputIteratorT,
680
            typename Range1T, 
681
            typename Range2T,
682
            typename Range3T>
683
        inline OutputIteratorT ireplace_all_copy(
684
            OutputIteratorT Output,
685
            const Range1T& Input,
686
            const Range2T& Search,
687
            const Range3T& Format,
688
            const std::locale& Loc=std::locale() )
689
        {
690
            return ::boost::algorithm::find_format_all_copy(
691
                Output,
692
                Input,
693
                ::boost::algorithm::first_finder(Search, is_iequal(Loc)),
694
                ::boost::algorithm::const_formatter(Format) );
695
        }
696
697
        //! Replace all algorithm ( case insensitive )
698
        /*!
699
            \overload
700
        */
701
        template<typename SequenceT, typename Range1T, typename Range2T>
702
        inline SequenceT ireplace_all_copy( 
703
            const SequenceT& Input,
704
            const Range1T& Search,
705
            const Range2T& Format,
706
            const std::locale& Loc=std::locale() )
707
        {
708
            return ::boost::algorithm::find_format_all_copy( 
709
                Input,
710
                ::boost::algorithm::first_finder(Search, is_iequal(Loc)),
711
                ::boost::algorithm::const_formatter(Format) );
712
        }
713
714
        //! Replace all algorithm ( case insensitive )
715
        /*!
716
            Replace all occurrences of the search string in the input 
717
            with the format string.The input sequence is modified in-place.
718
            Searching is case insensitive.
719
720
            \param Input An input string
721
            \param Search A substring to be searched for 
722
            \param Format A substitute string
723
            \param Loc A locale used for case insensitive comparison
724
        */
725
        template<typename SequenceT, typename Range1T, typename Range2T>
726
        inline void ireplace_all( 
727
            SequenceT& Input,
728
            const Range1T& Search,
729
            const Range2T& Format,
730
            const std::locale& Loc=std::locale() )
731
        {
732
            ::boost::algorithm::find_format_all( 
733
                Input, 
734
                ::boost::algorithm::first_finder(Search, is_iequal(Loc)),
735
                ::boost::algorithm::const_formatter(Format) );
736
        }
737
        
738
//  replace_head --------------------------------------------------------------------//
739
740
        //! Replace head algorithm
741
        /*!
742
            Replace the head of the input with the given format string. 
743
            The head is a prefix of a string of given size. 
744
            If the sequence is shorter then required, whole string if 
745
            considered to be the head. 
746
            The result is a modified copy of the input. It is returned as a sequence 
747
            or copied to the output iterator.
748
            
749
            \param Output An output iterator to which the result will be copied
750
            \param Input An input string
751
            \param N Length of the head.
752
                For N>=0, at most N characters are extracted.
753
                For N<0, size(Input)-|N| characters are extracted.
754
            \param Format A substitute string
755
            \return An output iterator pointing just after the last inserted character or
756
                a modified copy of the input  
757
758
            \note The second variant of this function provides the strong exception-safety guarantee
759
        */
760
        template<
761
            typename OutputIteratorT,
762
            typename Range1T, 
763
            typename Range2T>
764
        inline OutputIteratorT replace_head_copy(
765
            OutputIteratorT Output,
766
            const Range1T& Input,
767
            int N,
768
            const Range2T& Format )
769
        {
770
            return ::boost::algorithm::find_format_copy(
771
                Output,
772
                Input,
773
                ::boost::algorithm::head_finder(N),
774
                ::boost::algorithm::const_formatter(Format) );
775
        }
776
777
        //! Replace head algorithm
778
        /*!
779
            \overload
780
        */
781
        template<typename SequenceT, typename RangeT>
782
        inline SequenceT replace_head_copy( 
783
            const SequenceT& Input,
784
            int N,
785
            const RangeT& Format )
786
        {
787
            return ::boost::algorithm::find_format_copy( 
788
                Input,
789
                ::boost::algorithm::head_finder(N),
790
                ::boost::algorithm::const_formatter(Format) );
791
        }
792
793
        //! Replace head algorithm
794
        /*!
795
            Replace the head of the input with the given format string. 
796
            The head is a prefix of a string of given size. 
797
            If the sequence is shorter then required, the whole string is 
798
            considered to be the head. The input sequence is modified in-place.
799
800
            \param Input An input string
801
            \param N Length of the head.
802
                For N>=0, at most N characters are extracted.
803
                For N<0, size(Input)-|N| characters are extracted.
804
            \param Format A substitute string
805
        */
806
        template<typename SequenceT, typename RangeT>
807
        inline void replace_head( 
808
            SequenceT& Input,
809
            int N,
810
            const RangeT& Format )
811
        {
812
            ::boost::algorithm::find_format( 
813
                Input, 
814
                ::boost::algorithm::head_finder(N),
815
                ::boost::algorithm::const_formatter(Format) );
816
        }
817
818
//  replace_tail --------------------------------------------------------------------//
819
820
        //! Replace tail algorithm
821
        /*!
822
            Replace the tail of the input with the given format string. 
823
            The tail is a suffix of a string of given size. 
824
            If the sequence is shorter then required, whole string is 
825
            considered to be the tail. 
826
            The result is a modified copy of the input. It is returned as a sequence 
827
            or copied to the output iterator.
828
829
            \param Output An output iterator to which the result will be copied
830
            \param Input An input string
831
            \param N Length of the tail.
832
                For N>=0, at most N characters are extracted.
833
                For N<0, size(Input)-|N| characters are extracted.
834
            \param Format A substitute string
835
            \return An output iterator pointing just after the last inserted character or
836
                    a modified copy of the input   
837
838
              \note The second variant of this function provides the strong exception-safety guarantee
839
        */
840
        template<
841
            typename OutputIteratorT,
842
            typename Range1T, 
843
            typename Range2T>
844
        inline OutputIteratorT replace_tail_copy(
845
            OutputIteratorT Output,
846
            const Range1T& Input,
847
            int N,
848
            const Range2T& Format )
849
        {
850
            return ::boost::algorithm::find_format_copy(
851
                Output,
852
                Input,
853
                ::boost::algorithm::tail_finder(N),
854
                ::boost::algorithm::const_formatter(Format) );
855
        }
856
857
        //! Replace tail algorithm
858
        /*!
859
            \overload
860
        */
861
        template<typename SequenceT, typename RangeT>
862
        inline SequenceT replace_tail_copy( 
863
            const SequenceT& Input,
864
            int N,
865
            const RangeT& Format )
866
        {
867
            return ::boost::algorithm::find_format_copy( 
868
                Input,
869
                ::boost::algorithm::tail_finder(N),
870
                ::boost::algorithm::const_formatter(Format) );
871
        }
872
873
        //! Replace tail algorithm
874
        /*!
875
            Replace the tail of the input with the given format sequence. 
876
            The tail is a suffix of a string of given size. 
877
            If the sequence is shorter then required, the whole string is 
878
            considered to be the tail. The input sequence is modified in-place.
879
880
            \param Input An input string
881
            \param N Length of the tail.
882
                For N>=0, at most N characters are extracted.
883
                For N<0, size(Input)-|N| characters are extracted.
884
            \param Format A substitute string
885
        */
886
        template<typename SequenceT, typename RangeT>
887
        inline void replace_tail( 
888
            SequenceT& Input,
889
            int N,
890
            const RangeT& Format )
891
        {
892
            ::boost::algorithm::find_format( 
893
                Input, 
894
                ::boost::algorithm::tail_finder(N),
895
                ::boost::algorithm::const_formatter(Format) );
896
        }
897
898
    } // namespace algorithm
899
900
    // pull names to the boost namespace
901
    using algorithm::replace_range_copy;
902
    using algorithm::replace_range;
903
    using algorithm::replace_first_copy;
904
    using algorithm::replace_first;
905
    using algorithm::ireplace_first_copy;
906
    using algorithm::ireplace_first;
907
    using algorithm::replace_last_copy;
908
    using algorithm::replace_last;
909
    using algorithm::ireplace_last_copy;
910
    using algorithm::ireplace_last;
911
    using algorithm::replace_nth_copy;
912
    using algorithm::replace_nth;
913
    using algorithm::ireplace_nth_copy;
914
    using algorithm::ireplace_nth;
915
    using algorithm::replace_all_copy;
916
    using algorithm::replace_all;
917
    using algorithm::ireplace_all_copy;
918
    using algorithm::ireplace_all;
919
    using algorithm::replace_head_copy;
920
    using algorithm::replace_head;
921
    using algorithm::replace_tail_copy;
922
    using algorithm::replace_tail;
923
924
} // namespace boost
925
926
#endif  // BOOST_REPLACE_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/algorithm/string/split.hpp
Line
Count
Source
1
//  Boost string_algo library split.hpp header file  ---------------------------//
2
3
//  Copyright Pavol Droba 2002-2006.
4
//
5
// Distributed under the Boost Software License, Version 1.0.
6
//    (See accompanying file LICENSE_1_0.txt or copy at
7
//          http://www.boost.org/LICENSE_1_0.txt)
8
9
//  See http://www.boost.org/ for updates, documentation, and revision history.
10
11
#ifndef BOOST_STRING_SPLIT_HPP
12
#define BOOST_STRING_SPLIT_HPP
13
14
#include <boost/algorithm/string/config.hpp>
15
16
#include <boost/algorithm/string/iter_find.hpp>
17
#include <boost/algorithm/string/finder.hpp>
18
#include <boost/algorithm/string/compare.hpp>
19
20
/*! \file
21
    Defines basic split algorithms. 
22
    Split algorithms can be used to divide a string
23
    into several parts according to given criteria.
24
    
25
    Each part is copied and added as a new element to the
26
    output container.
27
    Thus the result container must be able to hold copies
28
    of the matches (in a compatible structure like std::string) or
29
    a reference to it (e.g. using the iterator range class).
30
    Examples of such a container are \c std::vector<std::string>
31
    or \c std::list<boost::iterator_range<std::string::iterator>>
32
*/
33
34
namespace boost {
35
    namespace algorithm {
36
37
//  find_all  ------------------------------------------------------------//
38
39
        //! Find all algorithm
40
        /*!
41
            This algorithm finds all occurrences of the search string
42
            in the input.
43
            
44
            Each part is copied and added as a new element to the
45
            output container.
46
            Thus the result container must be able to hold copies
47
            of the matches (in a compatible structure like std::string) or
48
            a reference to it (e.g. using the iterator range class).
49
            Examples of such a container are \c std::vector<std::string>
50
            or \c std::list<boost::iterator_range<std::string::iterator>>
51
52
            \param Result A container that can hold copies of references to the substrings
53
            \param Input A container which will be searched.
54
            \param Search A substring to be searched for.
55
            \return A reference the result
56
57
            \note Prior content of the result will be overwritten.
58
59
            \note This function provides the strong exception-safety guarantee
60
        */
61
        template< typename SequenceSequenceT, typename Range1T, typename Range2T >
62
        inline SequenceSequenceT& find_all(
63
            SequenceSequenceT& Result,
64
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
65
            Range1T&& Input,
66
#else
67
            Range1T& Input,
68
#endif
69
            const Range2T& Search)
70
        {
71
            return ::boost::algorithm::iter_find(
72
                Result,
73
                Input,
74
                ::boost::algorithm::first_finder(Search) );        
75
        }
76
77
        //! Find all algorithm ( case insensitive ) 
78
        /*!
79
            This algorithm finds all occurrences of the search string
80
            in the input. 
81
            Each part is copied and added as a new element to the
82
            output container. Thus the result container must be able to hold copies
83
            of the matches (in a compatible structure like std::string) or
84
            a reference to it (e.g. using the iterator range class).
85
            Examples of such a container are \c std::vector<std::string>
86
            or \c std::list<boost::iterator_range<std::string::iterator>>
87
88
            Searching is case insensitive.
89
90
            \param Result A container that can hold copies of references to the substrings
91
            \param Input A container which will be searched.
92
            \param Search A substring to be searched for.
93
            \param Loc A locale used for case insensitive comparison
94
            \return A reference the result
95
96
            \note Prior content of the result will be overwritten.
97
98
            \note This function provides the strong exception-safety guarantee
99
        */
100
        template< typename SequenceSequenceT, typename Range1T, typename Range2T >
101
        inline SequenceSequenceT& ifind_all(
102
            SequenceSequenceT& Result,
103
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
104
            Range1T&& Input,
105
#else
106
            Range1T& Input,
107
#endif
108
            const Range2T& Search,
109
            const std::locale& Loc=std::locale() )
110
        {
111
            return ::boost::algorithm::iter_find(
112
                Result,
113
                Input,
114
                ::boost::algorithm::first_finder(Search, is_iequal(Loc) ) );        
115
        }
116
117
118
//  tokenize  -------------------------------------------------------------//
119
120
        //! Split algorithm
121
        /*! 
122
            Tokenize expression. This function is equivalent to C strtok. Input
123
            sequence is split into tokens, separated by separators. Separators 
124
            are given by means of the predicate.
125
126
            Each part is copied and added as a new element to the
127
            output container.
128
            Thus the result container must be able to hold copies
129
            of the matches (in a compatible structure like std::string) or
130
            a reference to it (e.g. using the iterator range class).
131
            Examples of such a container are \c std::vector<std::string>
132
            or \c std::list<boost::iterator_range<std::string::iterator>>
133
    
134
            \param Result A container that can hold copies of references to the substrings          
135
            \param Input A container which will be searched.
136
            \param Pred A predicate to identify separators. This predicate is 
137
                supposed to return true if a given element is a separator.
138
            \param eCompress If eCompress argument is set to token_compress_on, adjacent 
139
                separators are merged together. Otherwise, every two separators
140
                delimit a token.
141
            \return A reference the result
142
143
            \note Prior content of the result will be overwritten.
144
145
            \note This function provides the strong exception-safety guarantee
146
        */
147
        template< typename SequenceSequenceT, typename RangeT, typename PredicateT >
148
        inline SequenceSequenceT& split(
149
            SequenceSequenceT& Result,
150
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
151
            RangeT&& Input,
152
#else
153
            RangeT& Input,
154
#endif
155
            PredicateT Pred,
156
            token_compress_mode_type eCompress=token_compress_off )
157
6
        {
158
6
            return ::boost::algorithm::iter_split(
159
6
                Result,
160
6
                Input,
161
6
                ::boost::algorithm::token_finder( Pred, eCompress ) );         
162
6
        }
163
164
    } // namespace algorithm
165
166
    // pull names to the boost namespace
167
    using algorithm::find_all;
168
    using algorithm::ifind_all;
169
    using algorithm::split;    
170
171
} // namespace boost
172
173
174
#endif  // BOOST_STRING_SPLIT_HPP
175
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/assert.hpp
Line
Count
Source
1
//
2
//  boost/assert.hpp - BOOST_ASSERT(expr)
3
//                     BOOST_ASSERT_MSG(expr, msg)
4
//                     BOOST_VERIFY(expr)
5
//                     BOOST_VERIFY_MSG(expr, msg)
6
//                     BOOST_ASSERT_IS_VOID
7
//
8
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
9
//  Copyright (c) 2007, 2014 Peter Dimov
10
//  Copyright (c) Beman Dawes 2011
11
//  Copyright (c) 2015 Ion Gaztanaga
12
//
13
//  Distributed under the Boost Software License, Version 1.0.
14
//  See accompanying file LICENSE_1_0.txt or copy at
15
//  http://www.boost.org/LICENSE_1_0.txt
16
//
17
//  Note: There are no include guards. This is intentional.
18
//
19
//  See http://www.boost.org/libs/assert/assert.html for documentation.
20
//
21
22
//
23
// Stop inspect complaining about use of 'assert':
24
//
25
// boostinspect:naassert_macro
26
//
27
28
//
29
// BOOST_ASSERT, BOOST_ASSERT_MSG, BOOST_ASSERT_IS_VOID
30
//
31
32
#undef BOOST_ASSERT
33
#undef BOOST_ASSERT_MSG
34
#undef BOOST_ASSERT_IS_VOID
35
36
#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) )
37
38
# define BOOST_ASSERT(expr) ((void)0)
39
# define BOOST_ASSERT_MSG(expr, msg) ((void)0)
40
# define BOOST_ASSERT_IS_VOID
41
42
#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) )
43
44
#include <boost/config.hpp> // for BOOST_LIKELY
45
#include <boost/current_function.hpp>
46
47
namespace boost
48
{
49
    void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
50
    void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined
51
} // namespace boost
52
53
#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
54
#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
55
56
#else
57
58
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
59
60
177
# define BOOST_ASSERT(expr) assert(expr)
61
# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg))
62
#if defined(NDEBUG)
63
# define BOOST_ASSERT_IS_VOID
64
#endif
65
66
#endif
67
68
//
69
// BOOST_VERIFY, BOOST_VERIFY_MSG
70
//
71
72
#undef BOOST_VERIFY
73
#undef BOOST_VERIFY_MSG
74
75
#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) )
76
77
# define BOOST_VERIFY(expr) ((void)(expr))
78
# define BOOST_VERIFY_MSG(expr, msg) ((void)(expr))
79
80
#else
81
82
# define BOOST_VERIFY(expr) BOOST_ASSERT(expr)
83
# define BOOST_VERIFY_MSG(expr, msg) BOOST_ASSERT_MSG(expr,msg)
84
85
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/assert/source_location.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED
2
#define BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED
3
4
//  http://www.boost.org/libs/assert
5
//
6
//  Copyright 2019 Peter Dimov
7
//  Distributed under the Boost Software License, Version 1.0.
8
//  http://www.boost.org/LICENSE_1_0.txt
9
10
#include <boost/current_function.hpp>
11
#include <boost/config.hpp>
12
#include <boost/cstdint.hpp>
13
#include <iosfwd>
14
15
namespace boost
16
{
17
18
struct source_location
19
{
20
private:
21
22
    char const * file_;
23
    char const * function_;
24
    boost::uint_least32_t line_;
25
    boost::uint_least32_t column_;
26
27
public:
28
29
    BOOST_CONSTEXPR source_location() BOOST_NOEXCEPT: file_( "(unknown)" ), function_( "(unknown)" ), line_( 0 ), column_( 0 )
30
0
    {
31
0
    }
32
33
    BOOST_CONSTEXPR source_location( char const * file, boost::uint_least32_t ln, char const * function, boost::uint_least32_t col = 0 ) BOOST_NOEXCEPT: file_( file ), function_( function ), line_( ln ), column_( col )
34
0
    {
35
0
    }
36
37
    BOOST_CONSTEXPR char const * file_name() const BOOST_NOEXCEPT
38
0
    {
39
0
        return file_;
40
0
    }
41
42
    BOOST_CONSTEXPR char const * function_name() const BOOST_NOEXCEPT
43
0
    {
44
0
        return function_;
45
0
    }
46
47
    BOOST_CONSTEXPR boost::uint_least32_t line() const BOOST_NOEXCEPT
48
0
    {
49
0
        return line_;
50
0
    }
51
52
    BOOST_CONSTEXPR boost::uint_least32_t column() const BOOST_NOEXCEPT
53
0
    {
54
0
        return column_;
55
0
    }
56
};
57
58
template<class E, class T> std::basic_ostream<E, T> & operator<<( std::basic_ostream<E, T> & os, source_location const & loc )
59
{
60
    os.width( 0 );
61
62
    if( loc.line() == 0 )
63
    {
64
        os << "(unknown source location)";
65
    }
66
    else
67
    {
68
        os << loc.file_name() << ':' << loc.line();
69
70
        if( loc.column() )
71
        {
72
            os << ':' << loc.column();
73
        }
74
75
        os << ": in function '" << loc.function_name() << '\'';
76
    }
77
78
    return os;
79
}
80
81
} // namespace boost
82
83
#if defined( BOOST_DISABLE_CURRENT_LOCATION )
84
85
#  define BOOST_CURRENT_LOCATION ::boost::source_location()
86
87
#elif defined(__clang_analyzer__)
88
89
// Cast to char const* to placate clang-tidy
90
// https://bugs.llvm.org/show_bug.cgi?id=28480
91
#  define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, static_cast<char const*>(BOOST_CURRENT_FUNCTION))
92
93
#else
94
95
#  define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION)
96
97
#endif
98
99
#endif // #ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/concept/assert.hpp
Line
Count
Source
1
// Copyright David Abrahams 2006. Distributed under the Boost
2
// Software License, Version 1.0. (See accompanying
3
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
#ifndef BOOST_CONCEPT_ASSERT_DWA2006430_HPP
5
# define BOOST_CONCEPT_ASSERT_DWA2006430_HPP
6
7
# include <boost/config.hpp>
8
# include <boost/config/workaround.hpp>
9
10
// The old protocol used a constraints() member function in concept
11
// checking classes.  If the compiler supports SFINAE, we can detect
12
// that function and seamlessly support the old concept checking
13
// classes.  In this release, backward compatibility with the old
14
// concept checking classes is enabled by default, where available.
15
// The old protocol is deprecated, though, and backward compatibility
16
// will no longer be the default in the next release.
17
18
# if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT)                                         \
19
    && !defined(BOOST_NO_SFINAE)                                                    \
20
                                                                                    \
21
    && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4))
22
23
// Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to
24
// check for the presence of particularmember functions.
25
26
#  define BOOST_OLD_CONCEPT_SUPPORT
27
28
# endif
29
30
# ifdef BOOST_MSVC
31
#  include <boost/concept/detail/msvc.hpp>
32
# elif BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
33
#  include <boost/concept/detail/borland.hpp>
34
# else 
35
#  include <boost/concept/detail/general.hpp>
36
# endif
37
38
  // Usage, in class or function context:
39
  //
40
  //     BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
41
  //
42
# define BOOST_CONCEPT_ASSERT(ModelInParens) \
43
36
    BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
44
45
#endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/concept/detail/general.hpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright David Abrahams 2006. Distributed under the Boost
2
// Software License, Version 1.0. (See accompanying
3
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
#ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
5
# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
6
7
# include <boost/config.hpp>
8
# include <boost/preprocessor/cat.hpp>
9
# include <boost/concept/detail/backward_compatibility.hpp>
10
11
# ifdef BOOST_OLD_CONCEPT_SUPPORT
12
#  include <boost/concept/detail/has_constraints.hpp>
13
#  include <boost/type_traits/conditional.hpp>
14
# endif
15
16
// This implementation works on Comeau and GCC, all the way back to
17
// 2.95
18
namespace boost { namespace concepts {
19
20
template <class ModelFn>
21
struct requirement_;
22
23
namespace detail
24
{
25
  template <void(*)()> struct instantiate {};
26
}
27
28
template <class Model>
29
struct requirement
30
{
31
#   if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
32
#   pragma GCC diagnostic push
33
#   pragma GCC diagnostic ignored "-Wnonnull"
34
#   endif
35
    static void failed() { ((Model*)0)->~Model(); }
36
#   if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
37
#   pragma GCC diagnostic pop
38
#   endif
39
};
40
41
struct failed {};
42
43
template <class Model>
44
struct requirement<failed ************ Model::************>
45
{
46
#   if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
47
#   pragma GCC diagnostic push
48
#   pragma GCC diagnostic ignored "-Wnonnull"
49
#   endif
50
0
    static void failed() { ((Model*)0)->~Model(); }
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS0_18usage_requirementsINS_17CopyConstructibleINSt3__111__wrap_iterIPKcEEEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS0_18usage_requirementsINS_11ConvertibleINS_9iterators27random_access_traversal_tagENS4_27incrementable_traversal_tagEEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS_11ConvertibleINS_9iterators27random_access_traversal_tagENS3_27incrementable_traversal_tagEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS0_18usage_requirementsINS_12range_detail28IncrementableIteratorConceptINSt3__111__wrap_iterIPKcEEEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS0_18usage_requirementsINS_18EqualityComparableINSt3__111__wrap_iterIPKcEEEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS0_18usage_requirementsINS_11ConvertibleINS_9iterators27random_access_traversal_tagENS4_25single_pass_traversal_tagEEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS_11ConvertibleINS_9iterators27random_access_traversal_tagENS3_25single_pass_traversal_tagEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS0_18usage_requirementsINS_12range_detail25SinglePassIteratorConceptINSt3__111__wrap_iterIPKcEEEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS_12range_detail25SinglePassIteratorConceptINSt3__111__wrap_iterIPKcEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS0_18usage_requirementsINS_22SinglePassRangeConceptIKNS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts11requirementIPPPPPPPPPPPMNS_22SinglePassRangeConceptIKNS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEEPPPPPPPPPPPPNS0_6failedEE6failedEv
51
#   if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
52
#   pragma GCC diagnostic pop
53
#   endif
54
};
55
56
# ifdef BOOST_OLD_CONCEPT_SUPPORT
57
58
template <class Model>
59
struct constraint
60
{
61
#   if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
62
#   pragma GCC diagnostic push
63
#   pragma GCC diagnostic ignored "-Wnonnull"
64
#   endif
65
0
    static void failed() { ((Model*)0)->constraints(); }
Unexecuted instantiation: _ZN5boost8concepts10constraintINS_9algorithm13FinderConceptINS2_6detail13token_finderFINS4_10is_any_ofFIcEEEENSt3__111__wrap_iterIPKcEEEEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts10constraintINS_9algorithm13FinderConceptINS2_6detail13first_finderFIPKcNS2_8is_equalEEENSt3__111__wrap_iterIS7_EEEEE6failedEv
Unexecuted instantiation: _ZN5boost8concepts10constraintINS_9algorithm16FormatterConceptINS2_6detail13const_formatFINS_14iterator_rangeIPKcEEEENS4_13first_finderFIS8_NS2_8is_equalEEENSt3__111__wrap_iterIS8_EEEEE6failedEv
66
#   if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
67
#   pragma GCC diagnostic pop
68
#   endif
69
};
70
  
71
template <class Model>
72
struct requirement_<void(*)(Model)>
73
  : boost::conditional<
74
        concepts::not_satisfied<Model>::value
75
      , constraint<Model>
76
      , requirement<failed ************ Model::************>
77
    >::type
78
{};
79
  
80
# else
81
82
// For GCC-2.x, these can't have exactly the same name
83
template <class Model>
84
struct requirement_<void(*)(Model)>
85
    : requirement<failed ************ Model::************>
86
{};
87
  
88
# endif
89
90
#  define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr )             \
91
36
    typedef ::boost::concepts::detail::instantiate<          \
92
36
    &::boost::concepts::requirement_<ModelFnPtr>::failed>    \
93
36
      BOOST_PP_CAT(boost_concept_check,__LINE__)             \
94
36
      BOOST_ATTRIBUTE_UNUSED
95
96
}}
97
98
#endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/concept_check.hpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// (C) Copyright Jeremy Siek 2000.
3
// Copyright 2002 The Trustees of Indiana University.
4
//
5
// Distributed under the Boost Software License, Version 1.0. (See
6
// accompanying file LICENSE_1_0.txt or copy at
7
// http://www.boost.org/LICENSE_1_0.txt)
8
//
9
// Revision History:
10
//   05 May   2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
11
//   02 April 2001: Removed limits header altogether. (Jeremy Siek)
12
//   01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
13
//
14
15
// See http://www.boost.org/libs/concept_check for documentation.
16
17
#ifndef BOOST_CONCEPT_CHECKS_HPP
18
# define BOOST_CONCEPT_CHECKS_HPP
19
20
# include <boost/concept/assert.hpp>
21
22
# include <iterator>
23
# include <boost/type_traits/conversion_traits.hpp>
24
# include <utility>
25
# include <boost/type_traits/is_same.hpp>
26
# include <boost/type_traits/is_void.hpp>
27
# include <boost/static_assert.hpp>
28
# include <boost/type_traits/integral_constant.hpp>
29
# include <boost/config/workaround.hpp>
30
31
# include <boost/concept/usage.hpp>
32
# include <boost/concept/detail/concept_def.hpp>
33
34
#if (defined _MSC_VER)
35
# pragma warning( push )
36
# pragma warning( disable : 4510 ) // default constructor could not be generated
37
# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
38
#endif
39
40
namespace boost
41
{
42
43
  //
44
  // Backward compatibility
45
  //
46
47
  template <class Model>
48
  inline void function_requires(Model* = 0)
49
  {
50
      BOOST_CONCEPT_ASSERT((Model));
51
  }
52
0
  template <class T> inline void ignore_unused_variable_warning(T const&) {}
Unexecuted instantiation: _ZN5boost30ignore_unused_variable_warningINSt3__111__wrap_iterIPKcEEEEvRKT_
Unexecuted instantiation: _ZN5boost30ignore_unused_variable_warningIPKNSt3__111__wrap_iterIPKcEEEEvRKT_
Unexecuted instantiation: _ZN5boost30ignore_unused_variable_warningIPNSt3__111__wrap_iterIPKcEEEEvRKT_
Unexecuted instantiation: _ZN5boost30ignore_unused_variable_warningINS_9iterators27incrementable_traversal_tagEEEvRKT_
Unexecuted instantiation: _ZN5boost30ignore_unused_variable_warningIbEEvRKT_
Unexecuted instantiation: _ZN5boost30ignore_unused_variable_warningINS_9iterators25single_pass_traversal_tagEEEvRKT_
Unexecuted instantiation: _ZN5boost30ignore_unused_variable_warningIcEEvRKT_
53
54
#  define BOOST_CLASS_REQUIRE(type_var, ns, concept)    \
55
    BOOST_CONCEPT_ASSERT((ns::concept<type_var>))
56
57
#  define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept)   \
58
    BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>))
59
60
#  define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept)  \
61
    BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>))
62
63
#  define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
64
    BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>))
65
66
67
  //
68
  // Begin concept definitions
69
  //
70
  BOOST_concept(Integer, (T))
71
  {
72
      BOOST_CONCEPT_USAGE(Integer)
73
        {
74
            x.error_type_must_be_an_integer_type();
75
        }
76
   private:
77
      T x;
78
  };
79
80
  template <> struct Integer<char> {};
81
  template <> struct Integer<signed char> {};
82
  template <> struct Integer<unsigned char> {};
83
  template <> struct Integer<short> {};
84
  template <> struct Integer<unsigned short> {};
85
  template <> struct Integer<int> {};
86
  template <> struct Integer<unsigned int> {};
87
  template <> struct Integer<long> {};
88
  template <> struct Integer<unsigned long> {};
89
# if defined(BOOST_HAS_LONG_LONG)
90
  template <> struct Integer< ::boost::long_long_type> {};
91
  template <> struct Integer< ::boost::ulong_long_type> {};
92
# elif defined(BOOST_HAS_MS_INT64)
93
  template <> struct Integer<__int64> {};
94
  template <> struct Integer<unsigned __int64> {};
95
# endif
96
97
  BOOST_concept(SignedInteger,(T)) {
98
    BOOST_CONCEPT_USAGE(SignedInteger) {
99
      x.error_type_must_be_a_signed_integer_type();
100
    }
101
   private:
102
    T x;
103
  };
104
  template <> struct SignedInteger<signed char> { };
105
  template <> struct SignedInteger<short> {};
106
  template <> struct SignedInteger<int> {};
107
  template <> struct SignedInteger<long> {};
108
# if defined(BOOST_HAS_LONG_LONG)
109
  template <> struct SignedInteger< ::boost::long_long_type> {};
110
# elif defined(BOOST_HAS_MS_INT64)
111
  template <> struct SignedInteger<__int64> {};
112
# endif
113
114
  BOOST_concept(UnsignedInteger,(T)) {
115
    BOOST_CONCEPT_USAGE(UnsignedInteger) {
116
      x.error_type_must_be_an_unsigned_integer_type();
117
    }
118
   private:
119
    T x;
120
  };
121
122
  template <> struct UnsignedInteger<unsigned char> {};
123
  template <> struct UnsignedInteger<unsigned short> {};
124
  template <> struct UnsignedInteger<unsigned int> {};
125
  template <> struct UnsignedInteger<unsigned long> {};
126
# if defined(BOOST_HAS_LONG_LONG)
127
  template <> struct UnsignedInteger< ::boost::ulong_long_type> {};
128
# elif defined(BOOST_HAS_MS_INT64)
129
  template <> struct UnsignedInteger<unsigned __int64> {};
130
# endif
131
132
  //===========================================================================
133
  // Basic Concepts
134
135
  BOOST_concept(DefaultConstructible,(TT))
136
  {
137
    BOOST_CONCEPT_USAGE(DefaultConstructible) {
138
      TT a;               // require default constructor
139
      ignore_unused_variable_warning(a);
140
    }
141
  };
142
143
  BOOST_concept(Assignable,(TT))
144
  {
145
    BOOST_CONCEPT_USAGE(Assignable) {
146
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
147
      a = b;             // require assignment operator
148
#endif
149
      const_constraints(b);
150
    }
151
   private:
152
    void const_constraints(const TT& x) {
153
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
154
      a = x;              // const required for argument to assignment
155
#else
156
      ignore_unused_variable_warning(x);
157
#endif
158
    }
159
   private:
160
    TT a;
161
    TT b;
162
  };
163
164
165
  BOOST_concept(CopyConstructible,(TT))
166
  {
167
    BOOST_CONCEPT_USAGE(CopyConstructible) {
168
      TT a(b);            // require copy constructor
169
      TT* ptr = &a;       // require address of operator
170
      const_constraints(a);
171
      ignore_unused_variable_warning(ptr);
172
    }
173
   private:
174
0
    void const_constraints(const TT& a) {
175
0
      TT c(a);            // require const copy constructor
176
0
      const TT* ptr = &a; // require const address of operator
177
0
      ignore_unused_variable_warning(c);
178
0
      ignore_unused_variable_warning(ptr);
179
0
    }
180
    TT b;
181
  };
182
183
  // The SGI STL version of Assignable requires copy constructor and operator=
184
  BOOST_concept(SGIAssignable,(TT))
185
  {
186
    BOOST_CONCEPT_USAGE(SGIAssignable) {
187
      TT c(a);
188
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
189
      a = b;              // require assignment operator
190
#endif
191
      const_constraints(b);
192
      ignore_unused_variable_warning(c);
193
    }
194
   private:
195
    void const_constraints(const TT& x) {
196
      TT c(x);
197
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
198
      a = x;              // const required for argument to assignment
199
#endif
200
      ignore_unused_variable_warning(c);
201
    }
202
    TT a;
203
    TT b;
204
  };
205
206
  BOOST_concept(Convertible,(X)(Y))
207
  {
208
    BOOST_CONCEPT_USAGE(Convertible) {
209
      Y y = x;
210
      ignore_unused_variable_warning(y);
211
    }
212
   private:
213
    X x;
214
  };
215
216
  // The C++ standard requirements for many concepts talk about return
217
  // types that must be "convertible to bool".  The problem with this
218
  // requirement is that it leaves the door open for evil proxies that
219
  // define things like operator|| with strange return types.  Two
220
  // possible solutions are:
221
  // 1) require the return type to be exactly bool
222
  // 2) stay with convertible to bool, and also
223
  //    specify stuff about all the logical operators.
224
  // For now we just test for convertible to bool.
225
  template <class TT>
226
0
  void require_boolean_expr(const TT& t) {
227
0
    bool x = t;
228
0
    ignore_unused_variable_warning(x);
229
0
  }
230
231
  BOOST_concept(EqualityComparable,(TT))
232
  {
233
    BOOST_CONCEPT_USAGE(EqualityComparable) {
234
      require_boolean_expr(a == b);
235
      require_boolean_expr(a != b);
236
    }
237
   private:
238
    TT a, b;
239
  };
240
241
  BOOST_concept(LessThanComparable,(TT))
242
  {
243
    BOOST_CONCEPT_USAGE(LessThanComparable) {
244
      require_boolean_expr(a < b);
245
    }
246
   private:
247
    TT a, b;
248
  };
249
250
  // This is equivalent to SGI STL's LessThanComparable.
251
  BOOST_concept(Comparable,(TT))
252
  {
253
    BOOST_CONCEPT_USAGE(Comparable) {
254
      require_boolean_expr(a < b);
255
      require_boolean_expr(a > b);
256
      require_boolean_expr(a <= b);
257
      require_boolean_expr(a >= b);
258
    }
259
   private:
260
    TT a, b;
261
  };
262
263
#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME)    \
264
  BOOST_concept(NAME, (First)(Second))                          \
265
  {                                                             \
266
      BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); }                         \
267
     private:                                                   \
268
        bool constraints_() { return a OP b; }                  \
269
        First a;                                                \
270
        Second b;                                               \
271
  }
272
273
#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME)    \
274
  BOOST_concept(NAME, (Ret)(First)(Second))                 \
275
  {                                                         \
276
      BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); }                     \
277
  private:                                                  \
278
      Ret constraints_() { return a OP b; }                 \
279
      First a;                                              \
280
      Second b;                                             \
281
  }
282
283
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp);
284
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp);
285
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp);
286
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp);
287
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp);
288
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp);
289
290
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp);
291
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp);
292
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp);
293
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp);
294
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp);
295
296
  //===========================================================================
297
  // Function Object Concepts
298
299
  BOOST_concept(Generator,(Func)(Return))
300
  {
301
      BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); }
302
303
   private:
304
      void test(boost::false_type)
305
      {
306
          // Do we really want a reference here?
307
          const Return& r = f();
308
          ignore_unused_variable_warning(r);
309
      }
310
311
      void test(boost::true_type)
312
      {
313
          f();
314
      }
315
316
      Func f;
317
  };
318
319
  BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
320
  {
321
      BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
322
323
   private:
324
      void test(boost::false_type)
325
      {
326
          f(arg);               // "priming the pump" this way keeps msvc6 happy (ICE)
327
          Return r = f(arg);
328
          ignore_unused_variable_warning(r);
329
      }
330
331
      void test(boost::true_type)
332
      {
333
          f(arg);
334
      }
335
336
#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
337
                      && BOOST_WORKAROUND(__GNUC__, > 3)))
338
      // Declare a dummy constructor to make gcc happy.
339
      // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type.
340
      // (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg"
341
      // in class without a constructor [-Wuninitialized])
342
      UnaryFunction();
343
#endif
344
345
      Func f;
346
      Arg arg;
347
  };
348
349
  BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
350
  {
351
      BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
352
   private:
353
      void test(boost::false_type)
354
      {
355
          (void) f(first,second);
356
          Return r = f(first, second); // require operator()
357
          (void)r;
358
      }
359
360
      void test(boost::true_type)
361
      {
362
          f(first,second);
363
      }
364
365
#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
366
                      && BOOST_WORKAROUND(__GNUC__, > 3)))
367
      // Declare a dummy constructor to make gcc happy.
368
      // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type.
369
      // (warning: non-static reference "const double& boost::BinaryFunction<YourClassHere>::arg"
370
      // in class without a constructor [-Wuninitialized])
371
      BinaryFunction();
372
#endif
373
374
      Func f;
375
      First first;
376
      Second second;
377
  };
378
379
  BOOST_concept(UnaryPredicate,(Func)(Arg))
380
  {
381
    BOOST_CONCEPT_USAGE(UnaryPredicate) {
382
      require_boolean_expr(f(arg)); // require operator() returning bool
383
    }
384
   private:
385
#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
386
                      && BOOST_WORKAROUND(__GNUC__, > 3)))
387
      // Declare a dummy constructor to make gcc happy.
388
      // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type.
389
      // (warning: non-static reference "const double& boost::UnaryPredicate<YourClassHere>::arg"
390
      // in class without a constructor [-Wuninitialized])
391
      UnaryPredicate();
392
#endif
393
394
    Func f;
395
    Arg arg;
396
  };
397
398
  BOOST_concept(BinaryPredicate,(Func)(First)(Second))
399
  {
400
    BOOST_CONCEPT_USAGE(BinaryPredicate) {
401
      require_boolean_expr(f(a, b)); // require operator() returning bool
402
    }
403
   private:
404
#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
405
                      && BOOST_WORKAROUND(__GNUC__, > 3)))
406
      // Declare a dummy constructor to make gcc happy.
407
      // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type.
408
      // (warning: non-static reference "const double& boost::BinaryPredicate<YourClassHere>::arg"
409
      // in class without a constructor [-Wuninitialized])
410
      BinaryPredicate();
411
#endif
412
    Func f;
413
    First a;
414
    Second b;
415
  };
416
417
  // use this when functor is used inside a container class like std::set
418
  BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
419
    : BinaryPredicate<Func, First, Second>
420
  {
421
    BOOST_CONCEPT_USAGE(Const_BinaryPredicate) {
422
      const_constraints(f);
423
    }
424
   private:
425
    void const_constraints(const Func& fun) {
426
      // operator() must be a const member function
427
      require_boolean_expr(fun(a, b));
428
    }
429
#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
430
                      && BOOST_WORKAROUND(__GNUC__, > 3)))
431
      // Declare a dummy constructor to make gcc happy.
432
      // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type.
433
      // (warning: non-static reference "const double& boost::Const_BinaryPredicate<YourClassHere>::arg"
434
      // in class without a constructor [-Wuninitialized])
435
      Const_BinaryPredicate();
436
#endif
437
438
    Func f;
439
    First a;
440
    Second b;
441
  };
442
443
  BOOST_concept(AdaptableGenerator,(Func)(Return))
444
    : Generator<Func, typename Func::result_type>
445
  {
446
      typedef typename Func::result_type result_type;
447
448
      BOOST_CONCEPT_USAGE(AdaptableGenerator)
449
      {
450
          BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
451
      }
452
  };
453
454
  BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
455
    : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
456
  {
457
      typedef typename Func::argument_type argument_type;
458
      typedef typename Func::result_type result_type;
459
460
      ~AdaptableUnaryFunction()
461
      {
462
          BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
463
          BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
464
      }
465
  };
466
467
  BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
468
    : BinaryFunction<
469
          Func
470
        , typename Func::result_type
471
        , typename Func::first_argument_type
472
        , typename Func::second_argument_type
473
      >
474
  {
475
      typedef typename Func::first_argument_type first_argument_type;
476
      typedef typename Func::second_argument_type second_argument_type;
477
      typedef typename Func::result_type result_type;
478
479
      ~AdaptableBinaryFunction()
480
      {
481
          BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
482
          BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
483
          BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
484
      }
485
  };
486
487
  BOOST_concept(AdaptablePredicate,(Func)(Arg))
488
    : UnaryPredicate<Func, Arg>
489
    , AdaptableUnaryFunction<Func, bool, Arg>
490
  {
491
  };
492
493
  BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
494
    : BinaryPredicate<Func, First, Second>
495
    , AdaptableBinaryFunction<Func, bool, First, Second>
496
  {
497
  };
498
499
  //===========================================================================
500
  // Iterator Concepts
501
502
  BOOST_concept(InputIterator,(TT))
503
    : Assignable<TT>
504
    , EqualityComparable<TT>
505
  {
506
      typedef typename std::iterator_traits<TT>::value_type value_type;
507
      typedef typename std::iterator_traits<TT>::difference_type difference_type;
508
      typedef typename std::iterator_traits<TT>::reference reference;
509
      typedef typename std::iterator_traits<TT>::pointer pointer;
510
      typedef typename std::iterator_traits<TT>::iterator_category iterator_category;
511
512
      BOOST_CONCEPT_USAGE(InputIterator)
513
      {
514
        BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
515
        BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
516
517
        TT j(i);
518
        (void)*i;           // require dereference operator
519
        ++j;                // require preincrement operator
520
        i++;                // require postincrement operator
521
      }
522
   private:
523
    TT i;
524
  };
525
526
  BOOST_concept(OutputIterator,(TT)(ValueT))
527
    : Assignable<TT>
528
  {
529
    BOOST_CONCEPT_USAGE(OutputIterator) {
530
531
      ++i;                // require preincrement operator
532
      i++;                // require postincrement operator
533
      *i++ = t;           // require postincrement and assignment
534
    }
535
   private:
536
    TT i, j;
537
    ValueT t;
538
  };
539
540
  BOOST_concept(ForwardIterator,(TT))
541
    : InputIterator<TT>
542
  {
543
      BOOST_CONCEPT_USAGE(ForwardIterator)
544
      {
545
          BOOST_CONCEPT_ASSERT((Convertible<
546
              BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
547
            , std::forward_iterator_tag
548
          >));
549
550
          typename InputIterator<TT>::reference r = *i;
551
          ignore_unused_variable_warning(r);
552
      }
553
554
   private:
555
      TT i;
556
  };
557
558
  BOOST_concept(Mutable_ForwardIterator,(TT))
559
    : ForwardIterator<TT>
560
  {
561
      BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
562
        *i++ = *j;         // require postincrement and assignment
563
      }
564
   private:
565
      TT i, j;
566
  };
567
568
  BOOST_concept(BidirectionalIterator,(TT))
569
    : ForwardIterator<TT>
570
  {
571
      BOOST_CONCEPT_USAGE(BidirectionalIterator)
572
      {
573
          BOOST_CONCEPT_ASSERT((Convertible<
574
              BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
575
            , std::bidirectional_iterator_tag
576
          >));
577
578
          --i;                // require predecrement operator
579
          i--;                // require postdecrement operator
580
      }
581
   private:
582
      TT i;
583
  };
584
585
  BOOST_concept(Mutable_BidirectionalIterator,(TT))
586
    : BidirectionalIterator<TT>
587
    , Mutable_ForwardIterator<TT>
588
  {
589
      BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
590
      {
591
          *i-- = *j;                  // require postdecrement and assignment
592
      }
593
   private:
594
      TT i, j;
595
  };
596
597
  BOOST_concept(RandomAccessIterator,(TT))
598
    : BidirectionalIterator<TT>
599
    , Comparable<TT>
600
  {
601
      BOOST_CONCEPT_USAGE(RandomAccessIterator)
602
      {
603
          BOOST_CONCEPT_ASSERT((Convertible<
604
              BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
605
            , std::random_access_iterator_tag
606
          >));
607
608
          i += n;             // require assignment addition operator
609
          i = i + n; i = n + i; // require addition with difference type
610
          i -= n;             // require assignment subtraction operator
611
          i = i - n;                  // require subtraction with difference type
612
          n = i - j;                  // require difference operator
613
          (void)i[n];                 // require element access operator
614
      }
615
616
   private:
617
    TT a, b;
618
    TT i, j;
619
      typename std::iterator_traits<TT>::difference_type n;
620
  };
621
622
  BOOST_concept(Mutable_RandomAccessIterator,(TT))
623
    : RandomAccessIterator<TT>
624
    , Mutable_BidirectionalIterator<TT>
625
  {
626
      BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
627
      {
628
          i[n] = *i;                  // require element access and assignment
629
      }
630
   private:
631
    TT i;
632
    typename std::iterator_traits<TT>::difference_type n;
633
  };
634
635
  //===========================================================================
636
  // Container s
637
638
  BOOST_concept(Container,(C))
639
    : Assignable<C>
640
  {
641
    typedef typename C::value_type value_type;
642
    typedef typename C::difference_type difference_type;
643
    typedef typename C::size_type size_type;
644
    typedef typename C::const_reference const_reference;
645
    typedef typename C::const_pointer const_pointer;
646
    typedef typename C::const_iterator const_iterator;
647
648
      BOOST_CONCEPT_USAGE(Container)
649
      {
650
          BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
651
          const_constraints(c);
652
      }
653
654
   private:
655
      void const_constraints(const C& cc) {
656
          i = cc.begin();
657
          i = cc.end();
658
          n = cc.size();
659
          n = cc.max_size();
660
          b = cc.empty();
661
      }
662
      C c;
663
      bool b;
664
      const_iterator i;
665
      size_type n;
666
  };
667
668
  BOOST_concept(Mutable_Container,(C))
669
    : Container<C>
670
  {
671
      typedef typename C::reference reference;
672
      typedef typename C::iterator iterator;
673
      typedef typename C::pointer pointer;
674
675
      BOOST_CONCEPT_USAGE(Mutable_Container)
676
      {
677
          BOOST_CONCEPT_ASSERT((
678
               Assignable<typename Mutable_Container::value_type>));
679
680
          BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
681
682
          i = c.begin();
683
          i = c.end();
684
          c.swap(c2);
685
      }
686
687
   private:
688
      iterator i;
689
      C c, c2;
690
  };
691
692
  BOOST_concept(ForwardContainer,(C))
693
    : Container<C>
694
  {
695
      BOOST_CONCEPT_USAGE(ForwardContainer)
696
      {
697
          BOOST_CONCEPT_ASSERT((
698
               ForwardIterator<
699
                    typename ForwardContainer::const_iterator
700
               >));
701
      }
702
  };
703
704
  BOOST_concept(Mutable_ForwardContainer,(C))
705
    : ForwardContainer<C>
706
    , Mutable_Container<C>
707
  {
708
      BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
709
      {
710
          BOOST_CONCEPT_ASSERT((
711
               Mutable_ForwardIterator<
712
                   typename Mutable_ForwardContainer::iterator
713
               >));
714
      }
715
  };
716
717
  BOOST_concept(ReversibleContainer,(C))
718
    : ForwardContainer<C>
719
  {
720
      typedef typename
721
        C::const_reverse_iterator
722
      const_reverse_iterator;
723
724
      BOOST_CONCEPT_USAGE(ReversibleContainer)
725
      {
726
          BOOST_CONCEPT_ASSERT((
727
              BidirectionalIterator<
728
                  typename ReversibleContainer::const_iterator>));
729
730
          BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
731
732
          const_constraints(c);
733
      }
734
   private:
735
      void const_constraints(const C& cc)
736
      {
737
          const_reverse_iterator _i = cc.rbegin();
738
          _i = cc.rend();
739
      }
740
      C c;
741
  };
742
743
  BOOST_concept(Mutable_ReversibleContainer,(C))
744
    : Mutable_ForwardContainer<C>
745
    , ReversibleContainer<C>
746
  {
747
      typedef typename C::reverse_iterator reverse_iterator;
748
749
      BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
750
      {
751
          typedef typename Mutable_ForwardContainer<C>::iterator iterator;
752
          BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
753
          BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
754
755
          reverse_iterator i = c.rbegin();
756
          i = c.rend();
757
      }
758
   private:
759
      C c;
760
  };
761
762
  BOOST_concept(RandomAccessContainer,(C))
763
    : ReversibleContainer<C>
764
  {
765
      typedef typename C::size_type size_type;
766
      typedef typename C::const_reference const_reference;
767
768
      BOOST_CONCEPT_USAGE(RandomAccessContainer)
769
      {
770
          BOOST_CONCEPT_ASSERT((
771
              RandomAccessIterator<
772
                  typename RandomAccessContainer::const_iterator
773
              >));
774
775
          const_constraints(c);
776
      }
777
   private:
778
      void const_constraints(const C& cc)
779
      {
780
          const_reference r = cc[n];
781
          ignore_unused_variable_warning(r);
782
      }
783
784
      C c;
785
      size_type n;
786
  };
787
788
  BOOST_concept(Mutable_RandomAccessContainer,(C))
789
    : Mutable_ReversibleContainer<C>
790
    , RandomAccessContainer<C>
791
  {
792
   private:
793
      typedef Mutable_RandomAccessContainer self;
794
   public:
795
      BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
796
      {
797
          BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
798
          BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
799
800
          typename self::reference r = c[i];
801
          ignore_unused_variable_warning(r);
802
      }
803
804
   private:
805
      typename Mutable_ReversibleContainer<C>::size_type i;
806
      C c;
807
  };
808
809
  // A Sequence is inherently mutable
810
  BOOST_concept(Sequence,(S))
811
    : Mutable_ForwardContainer<S>
812
      // Matt Austern's book puts DefaultConstructible here, the C++
813
      // standard places it in Container --JGS
814
      // ... so why aren't we following the standard?  --DWA
815
    , DefaultConstructible<S>
816
  {
817
      BOOST_CONCEPT_USAGE(Sequence)
818
      {
819
          S
820
              c(n, t),
821
              c2(first, last);
822
823
          c.insert(p, t);
824
          c.insert(p, n, t);
825
          c.insert(p, first, last);
826
827
          c.erase(p);
828
          c.erase(p, q);
829
830
          typename Sequence::reference r = c.front();
831
832
          ignore_unused_variable_warning(c);
833
          ignore_unused_variable_warning(c2);
834
          ignore_unused_variable_warning(r);
835
          const_constraints(c);
836
      }
837
   private:
838
      void const_constraints(const S& c) {
839
          typename Sequence::const_reference r = c.front();
840
          ignore_unused_variable_warning(r);
841
      }
842
843
      typename S::value_type t;
844
      typename S::size_type n;
845
      typename S::value_type* first, *last;
846
      typename S::iterator p, q;
847
  };
848
849
  BOOST_concept(FrontInsertionSequence,(S))
850
    : Sequence<S>
851
  {
852
      BOOST_CONCEPT_USAGE(FrontInsertionSequence)
853
      {
854
          c.push_front(t);
855
          c.pop_front();
856
      }
857
   private:
858
      S c;
859
      typename S::value_type t;
860
  };
861
862
  BOOST_concept(BackInsertionSequence,(S))
863
    : Sequence<S>
864
  {
865
      BOOST_CONCEPT_USAGE(BackInsertionSequence)
866
      {
867
          c.push_back(t);
868
          c.pop_back();
869
          typename BackInsertionSequence::reference r = c.back();
870
          ignore_unused_variable_warning(r);
871
          const_constraints(c);
872
      }
873
   private:
874
      void const_constraints(const S& cc) {
875
          typename BackInsertionSequence::const_reference
876
              r = cc.back();
877
          ignore_unused_variable_warning(r);
878
      }
879
      S c;
880
      typename S::value_type t;
881
  };
882
883
  BOOST_concept(AssociativeContainer,(C))
884
    : ForwardContainer<C>
885
    , DefaultConstructible<C>
886
  {
887
      typedef typename C::key_type key_type;
888
      typedef typename C::key_compare key_compare;
889
      typedef typename C::value_compare value_compare;
890
      typedef typename C::iterator iterator;
891
892
      BOOST_CONCEPT_USAGE(AssociativeContainer)
893
      {
894
          i = c.find(k);
895
          r = c.equal_range(k);
896
          c.erase(k);
897
          c.erase(i);
898
          c.erase(r.first, r.second);
899
          const_constraints(c);
900
          BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
901
902
          typedef typename AssociativeContainer::value_type value_type_;
903
          BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
904
      }
905
906
      // Redundant with the base concept, but it helps below.
907
      typedef typename C::const_iterator const_iterator;
908
   private:
909
      void const_constraints(const C& cc)
910
      {
911
          ci = cc.find(k);
912
          n = cc.count(k);
913
          cr = cc.equal_range(k);
914
      }
915
916
      C c;
917
      iterator i;
918
      std::pair<iterator,iterator> r;
919
      const_iterator ci;
920
      std::pair<const_iterator,const_iterator> cr;
921
      typename C::key_type k;
922
      typename C::size_type n;
923
  };
924
925
  BOOST_concept(UniqueAssociativeContainer,(C))
926
    : AssociativeContainer<C>
927
  {
928
      BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
929
      {
930
          C c(first, last);
931
932
          pos_flag = c.insert(t);
933
          c.insert(first, last);
934
935
          ignore_unused_variable_warning(c);
936
      }
937
   private:
938
      std::pair<typename C::iterator, bool> pos_flag;
939
      typename C::value_type t;
940
      typename C::value_type* first, *last;
941
  };
942
943
  BOOST_concept(MultipleAssociativeContainer,(C))
944
    : AssociativeContainer<C>
945
  {
946
      BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
947
      {
948
          C c(first, last);
949
950
          pos = c.insert(t);
951
          c.insert(first, last);
952
953
          ignore_unused_variable_warning(c);
954
          ignore_unused_variable_warning(pos);
955
      }
956
   private:
957
      typename C::iterator pos;
958
      typename C::value_type t;
959
      typename C::value_type* first, *last;
960
  };
961
962
  BOOST_concept(SimpleAssociativeContainer,(C))
963
    : AssociativeContainer<C>
964
  {
965
      BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
966
      {
967
          typedef typename C::key_type key_type;
968
          typedef typename C::value_type value_type;
969
          BOOST_STATIC_ASSERT((boost::is_same<key_type,value_type>::value));
970
      }
971
  };
972
973
  BOOST_concept(PairAssociativeContainer,(C))
974
    : AssociativeContainer<C>
975
  {
976
      BOOST_CONCEPT_USAGE(PairAssociativeContainer)
977
      {
978
          typedef typename C::key_type key_type;
979
          typedef typename C::value_type value_type;
980
          typedef typename C::mapped_type mapped_type;
981
          typedef std::pair<const key_type, mapped_type> required_value_type;
982
          BOOST_STATIC_ASSERT((boost::is_same<value_type,required_value_type>::value));
983
      }
984
  };
985
986
  BOOST_concept(SortedAssociativeContainer,(C))
987
    : AssociativeContainer<C>
988
    , ReversibleContainer<C>
989
  {
990
      BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
991
      {
992
          C
993
              c(kc),
994
              c2(first, last),
995
              c3(first, last, kc);
996
997
          p = c.upper_bound(k);
998
          p = c.lower_bound(k);
999
          r = c.equal_range(k);
1000
1001
          c.insert(p, t);
1002
1003
          ignore_unused_variable_warning(c);
1004
          ignore_unused_variable_warning(c2);
1005
          ignore_unused_variable_warning(c3);
1006
          const_constraints(c);
1007
      }
1008
1009
      void const_constraints(const C& c)
1010
      {
1011
          kc = c.key_comp();
1012
          vc = c.value_comp();
1013
1014
          cp = c.upper_bound(k);
1015
          cp = c.lower_bound(k);
1016
          cr = c.equal_range(k);
1017
      }
1018
1019
   private:
1020
      typename C::key_compare kc;
1021
      typename C::value_compare vc;
1022
      typename C::value_type t;
1023
      typename C::key_type k;
1024
      typedef typename C::iterator iterator;
1025
      typedef typename C::const_iterator const_iterator;
1026
1027
      typedef SortedAssociativeContainer self;
1028
      iterator p;
1029
      const_iterator cp;
1030
      std::pair<typename self::iterator,typename self::iterator> r;
1031
      std::pair<typename self::const_iterator,typename self::const_iterator> cr;
1032
      typename C::value_type* first, *last;
1033
  };
1034
1035
  // HashedAssociativeContainer
1036
1037
  BOOST_concept(Collection,(C))
1038
  {
1039
      BOOST_CONCEPT_USAGE(Collection)
1040
      {
1041
        boost::function_requires<boost::InputIteratorConcept<iterator> >();
1042
        boost::function_requires<boost::InputIteratorConcept<const_iterator> >();
1043
        boost::function_requires<boost::CopyConstructibleConcept<value_type> >();
1044
        const_constraints(c);
1045
        i = c.begin();
1046
        i = c.end();
1047
        c.swap(c);
1048
      }
1049
1050
      void const_constraints(const C& cc) {
1051
        ci = cc.begin();
1052
        ci = cc.end();
1053
        n = cc.size();
1054
        b = cc.empty();
1055
      }
1056
1057
    private:
1058
      typedef typename C::value_type value_type;
1059
      typedef typename C::iterator iterator;
1060
      typedef typename C::const_iterator const_iterator;
1061
      typedef typename C::reference reference;
1062
      typedef typename C::const_reference const_reference;
1063
      // typedef typename C::pointer pointer;
1064
      typedef typename C::difference_type difference_type;
1065
      typedef typename C::size_type size_type;
1066
1067
      C c;
1068
      bool b;
1069
      iterator i;
1070
      const_iterator ci;
1071
      size_type n;
1072
  };
1073
} // namespace boost
1074
1075
#if (defined _MSC_VER)
1076
# pragma warning( pop )
1077
#endif
1078
1079
# include <boost/concept/detail/concept_undef.hpp>
1080
1081
#endif // BOOST_CONCEPT_CHECKS_HPP
1082
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/config/compiler/clang.hpp
Line
Count
Source
1
// (C) Copyright Douglas Gregor 2010
2
//
3
//  Use, modification and distribution are subject to the
4
//  Boost Software License, Version 1.0. (See accompanying file
5
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7
//  See http://www.boost.org for most recent version.
8
9
// Clang compiler setup.
10
11
#define BOOST_HAS_PRAGMA_ONCE
12
13
// Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used.
14
#if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4))
15
#   define BOOST_HAS_PRAGMA_DETECT_MISMATCH
16
#endif
17
18
// When compiling with clang before __has_extension was defined,
19
// even if one writes 'defined(__has_extension) && __has_extension(xxx)',
20
// clang reports a compiler error. So the only workaround found is:
21
22
#ifndef __has_extension
23
#define __has_extension __has_feature
24
#endif
25
26
#ifndef __has_attribute
27
#define __has_attribute(x) 0
28
#endif
29
30
#ifndef __has_cpp_attribute
31
#define __has_cpp_attribute(x) 0
32
#endif
33
34
#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS)
35
#  define BOOST_NO_EXCEPTIONS
36
#endif
37
38
#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI)
39
#  define BOOST_NO_RTTI
40
#endif
41
42
#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID)
43
#  define BOOST_NO_TYPEID
44
#endif
45
46
#if !__has_feature(cxx_thread_local)
47
#  define BOOST_NO_CXX11_THREAD_LOCAL
48
#endif
49
50
#ifdef __is_identifier
51
#if !__is_identifier(__int64) && !defined(__GNUC__)
52
#  define BOOST_HAS_MS_INT64
53
#endif
54
#endif
55
56
#if __has_include(<stdint.h>)
57
#  define BOOST_HAS_STDINT_H
58
#endif
59
60
#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC)
61
#if (__clang_major__ >= 4) && defined(__has_include)
62
#if __has_include(<quadmath.h>)
63
#  define BOOST_HAS_FLOAT128
64
#endif
65
#endif
66
#endif
67
68
69
#define BOOST_HAS_NRVO
70
71
// Branch prediction hints
72
#if !defined (__c2__) && defined(__has_builtin)
73
#if __has_builtin(__builtin_expect)
74
#define BOOST_LIKELY(x) __builtin_expect(x, 1)
75
#define BOOST_UNLIKELY(x) __builtin_expect(x, 0)
76
#endif
77
#endif
78
79
// Clang supports "long long" in all compilation modes.
80
#define BOOST_HAS_LONG_LONG
81
82
//
83
// We disable this if the compiler is really nvcc with C++03 as it
84
// doesn't actually support __int128 as of CUDA_VERSION=7500
85
// even though it defines __SIZEOF_INT128__.
86
// See https://svn.boost.org/trac/boost/ticket/10418
87
//     https://svn.boost.org/trac/boost/ticket/11852
88
// Only re-enable this for nvcc if you're absolutely sure
89
// of the circumstances under which it's supported.
90
// Similarly __SIZEOF_INT128__ is defined when targetting msvc
91
// compatibility even though the required support functions are absent.
92
//
93
#if defined(__CUDACC__)
94
#  if defined(BOOST_GCC_CXX11)
95
#    define BOOST_NVCC_CXX11
96
#  else
97
#    define BOOST_NVCC_CXX03
98
#  endif
99
#endif
100
101
#if defined(__SIZEOF_INT128__) && !defined(BOOST_NVCC_CXX03) && !defined(_MSC_VER)
102
#  define BOOST_HAS_INT128
103
#endif
104
105
106
//
107
// Dynamic shared object (DSO) and dynamic-link library (DLL) support
108
//
109
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
110
#  define BOOST_HAS_DECLSPEC
111
#  define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__))
112
#  define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__))
113
#else
114
#  define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default")))
115
#  define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default")))
116
#  define BOOST_SYMBOL_IMPORT
117
#endif
118
119
//
120
// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through
121
// between switch labels.
122
//
123
#if __cplusplus >= 201103L && defined(__has_warning)
124
#  if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
125
50
#    define BOOST_FALLTHROUGH [[clang::fallthrough]]
126
#  endif
127
#endif
128
129
#if !__has_feature(cxx_auto_type)
130
#  define BOOST_NO_CXX11_AUTO_DECLARATIONS
131
#  define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS
132
#endif
133
134
//
135
// Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t
136
//
137
#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
138
#  define BOOST_NO_CXX11_CHAR16_T
139
#  define BOOST_NO_CXX11_CHAR32_T
140
#endif
141
142
#if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(__GNUC__)
143
#define BOOST_HAS_EXPM1
144
#define BOOST_HAS_LOG1P
145
#endif
146
147
#if !__has_feature(cxx_constexpr)
148
#  define BOOST_NO_CXX11_CONSTEXPR
149
#endif
150
151
#if !__has_feature(cxx_decltype)
152
#  define BOOST_NO_CXX11_DECLTYPE
153
#endif
154
155
#if !__has_feature(cxx_decltype_incomplete_return_types)
156
#  define BOOST_NO_CXX11_DECLTYPE_N3276
157
#endif
158
159
#if !__has_feature(cxx_defaulted_functions)
160
#  define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
161
#endif
162
163
#if !__has_feature(cxx_deleted_functions)
164
#  define BOOST_NO_CXX11_DELETED_FUNCTIONS
165
#endif
166
167
#if !__has_feature(cxx_explicit_conversions)
168
#  define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
169
#endif
170
171
#if !__has_feature(cxx_default_function_template_args)
172
#  define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
173
#endif
174
175
#if !__has_feature(cxx_generalized_initializers)
176
#  define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
177
#endif
178
179
#if !__has_feature(cxx_lambdas)
180
#  define BOOST_NO_CXX11_LAMBDAS
181
#endif
182
183
#if !__has_feature(cxx_local_type_template_args)
184
#  define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS
185
#endif
186
187
#if !__has_feature(cxx_noexcept)
188
#  define BOOST_NO_CXX11_NOEXCEPT
189
#endif
190
191
#if !__has_feature(cxx_nullptr)
192
#  define BOOST_NO_CXX11_NULLPTR
193
#endif
194
195
#if !__has_feature(cxx_range_for)
196
#  define BOOST_NO_CXX11_RANGE_BASED_FOR
197
#endif
198
199
#if !__has_feature(cxx_raw_string_literals)
200
#  define BOOST_NO_CXX11_RAW_LITERALS
201
#endif
202
203
#if !__has_feature(cxx_reference_qualified_functions)
204
#  define BOOST_NO_CXX11_REF_QUALIFIERS
205
#endif
206
207
#if !__has_feature(cxx_generalized_initializers)
208
#  define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
209
#endif
210
211
#if !__has_feature(cxx_rvalue_references)
212
#  define BOOST_NO_CXX11_RVALUE_REFERENCES
213
#endif
214
215
#if !__has_feature(cxx_strong_enums)
216
#  define BOOST_NO_CXX11_SCOPED_ENUMS
217
#endif
218
219
#if !__has_feature(cxx_static_assert)
220
#  define BOOST_NO_CXX11_STATIC_ASSERT
221
#endif
222
223
#if !__has_feature(cxx_alias_templates)
224
#  define BOOST_NO_CXX11_TEMPLATE_ALIASES
225
#endif
226
227
#if !__has_feature(cxx_unicode_literals)
228
#  define BOOST_NO_CXX11_UNICODE_LITERALS
229
#endif
230
231
#if !__has_feature(cxx_variadic_templates)
232
#  define BOOST_NO_CXX11_VARIADIC_TEMPLATES
233
#endif
234
235
#if !__has_feature(cxx_user_literals)
236
#  define BOOST_NO_CXX11_USER_DEFINED_LITERALS
237
#endif
238
239
#if !__has_feature(cxx_alignas)
240
#  define BOOST_NO_CXX11_ALIGNAS
241
#endif
242
243
#if !__has_feature(cxx_trailing_return)
244
#  define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
245
#endif
246
247
#if !__has_feature(cxx_inline_namespaces)
248
#  define BOOST_NO_CXX11_INLINE_NAMESPACES
249
#endif
250
251
#if !__has_feature(cxx_override_control)
252
#  define BOOST_NO_CXX11_FINAL
253
#  define BOOST_NO_CXX11_OVERRIDE
254
#endif
255
256
#if !__has_feature(cxx_unrestricted_unions)
257
#  define BOOST_NO_CXX11_UNRESTRICTED_UNION
258
#endif
259
260
#if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__))
261
#  define BOOST_NO_CXX14_BINARY_LITERALS
262
#endif
263
264
#if !__has_feature(__cxx_decltype_auto__)
265
#  define BOOST_NO_CXX14_DECLTYPE_AUTO
266
#endif
267
268
#if !__has_feature(__cxx_aggregate_nsdmi__)
269
#  define BOOST_NO_CXX14_AGGREGATE_NSDMI
270
#endif
271
272
#if !__has_feature(__cxx_init_captures__)
273
#  define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
274
#endif
275
276
#if !__has_feature(__cxx_generic_lambdas__)
277
#  define BOOST_NO_CXX14_GENERIC_LAMBDAS
278
#endif
279
280
// clang < 3.5 has a defect with dependent type, like following.
281
//
282
//  template <class T>
283
//  constexpr typename enable_if<pred<T> >::type foo(T &)
284
//  { } // error: no return statement in constexpr function
285
//
286
// This issue also affects C++11 mode, but C++11 constexpr requires return stmt.
287
// Therefore we don't care such case.
288
//
289
// Note that we can't check Clang version directly as the numbering system changes depending who's
290
// creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873)
291
// so instead verify that we have a feature that was introduced at the same time as working C++14
292
// constexpr (generic lambda's in this case):
293
//
294
#if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__)
295
#  define BOOST_NO_CXX14_CONSTEXPR
296
#endif
297
298
#if !__has_feature(__cxx_return_type_deduction__)
299
#  define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION
300
#endif
301
302
#if !__has_feature(__cxx_variable_templates__)
303
#  define BOOST_NO_CXX14_VARIABLE_TEMPLATES
304
#endif
305
306
#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606)
307
#  define BOOST_NO_CXX17_STRUCTURED_BINDINGS
308
#endif
309
310
#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606)
311
#  define BOOST_NO_CXX17_IF_CONSTEXPR
312
#endif
313
314
// Clang 3.9+ in c++1z
315
#if !__has_cpp_attribute(fallthrough) || __cplusplus < 201406L
316
#  define BOOST_NO_CXX17_INLINE_VARIABLES
317
#  define BOOST_NO_CXX17_FOLD_EXPRESSIONS
318
#endif
319
320
#if __cplusplus < 201103L
321
#define BOOST_NO_CXX11_SFINAE_EXPR
322
#endif
323
324
#if __cplusplus < 201400
325
// All versions with __cplusplus above this value seem to support this:
326
#  define BOOST_NO_CXX14_DIGIT_SEPARATORS
327
#endif
328
//
329
// __builtin_unreachable:
330
#if defined(__has_builtin) && __has_builtin(__builtin_unreachable)
331
#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable();
332
#endif
333
334
#if (__clang_major__ == 3) && (__clang_minor__ == 0)
335
// Apparently a clang bug:
336
#  define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS
337
#endif
338
339
// Clang has supported the 'unused' attribute since the first release.
340
#define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__))
341
342
// Type aliasing hint.
343
#if __has_attribute(__may_alias__)
344
#  define BOOST_MAY_ALIAS __attribute__((__may_alias__))
345
#endif
346
347
#ifndef BOOST_COMPILER
348
#  define BOOST_COMPILER "Clang version " __clang_version__
349
#endif
350
351
// Macro used to identify the Clang compiler.
352
#define BOOST_CLANG 1
353
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/container_hash/detail/hash_float.hpp
Line
Count
Source (jump to first uncovered line)
1
2
// Copyright 2005-2012 Daniel James.
3
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
7
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
8
9
#include <boost/config.hpp>
10
#if defined(BOOST_HAS_PRAGMA_ONCE)
11
#pragma once
12
#endif
13
14
#include <boost/container_hash/detail/float_functions.hpp>
15
#include <boost/container_hash/detail/limits.hpp>
16
#include <boost/core/enable_if.hpp>
17
#include <boost/integer/static_log2.hpp>
18
#include <boost/cstdint.hpp>
19
#include <boost/assert.hpp>
20
#include <boost/limits.hpp>
21
#include <cstring>
22
23
#if defined(BOOST_MSVC)
24
#pragma warning(push)
25
#if BOOST_MSVC >= 1400
26
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
27
                              // not satisfy test. Loop body not executed
28
#endif
29
#endif
30
31
// Can we use fpclassify?
32
33
// STLport
34
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
35
#define BOOST_HASH_USE_FPCLASSIFY 0
36
37
// GNU libstdc++ 3
38
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
39
#  if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
40
      !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
41
#    define BOOST_HASH_USE_FPCLASSIFY 1
42
#  else
43
#    define BOOST_HASH_USE_FPCLASSIFY 0
44
#  endif
45
46
// Everything else
47
#else
48
#  define BOOST_HASH_USE_FPCLASSIFY 0
49
#endif
50
51
namespace boost
52
{
53
    namespace hash_detail
54
    {
55
        inline void hash_float_combine(std::size_t& seed, std::size_t value)
56
0
        {
57
0
            seed ^= value + (seed<<6) + (seed>>2);
58
0
        }
59
60
        ////////////////////////////////////////////////////////////////////////
61
        // Binary hash function
62
        //
63
        // Only used for floats with known iec559 floats, and certain values in
64
        // numeric_limits
65
66
        inline std::size_t hash_binary(char* ptr, std::size_t length)
67
0
        {
68
0
            std::size_t seed = 0;
69
0
70
0
            if (length >= sizeof(std::size_t)) {
71
0
                std::memcpy(&seed, ptr, sizeof(std::size_t));
72
0
                length -= sizeof(std::size_t);
73
0
                ptr += sizeof(std::size_t);
74
0
75
0
                while(length >= sizeof(std::size_t)) {
76
0
                    std::size_t buffer = 0;
77
0
                    std::memcpy(&buffer, ptr, sizeof(std::size_t));
78
0
                    hash_float_combine(seed, buffer);
79
0
                    length -= sizeof(std::size_t);
80
0
                    ptr += sizeof(std::size_t);
81
0
                }
82
0
            }
83
0
84
0
            if (length > 0) {
85
0
                std::size_t buffer = 0;
86
0
                std::memcpy(&buffer, ptr, length);
87
0
                hash_float_combine(seed, buffer);
88
0
            }
89
0
90
0
            return seed;
91
0
        }
92
93
        template <typename Float, unsigned digits, unsigned max_exponent>
94
        struct enable_binary_hash
95
        {
96
            BOOST_STATIC_CONSTANT(bool, value =
97
                std::numeric_limits<Float>::is_iec559 &&
98
                std::numeric_limits<Float>::digits == digits &&
99
                std::numeric_limits<Float>::radix == 2 &&
100
                std::numeric_limits<Float>::max_exponent == max_exponent);
101
        };
102
103
        template <typename Float>
104
        inline std::size_t float_hash_impl(Float v,
105
            BOOST_DEDUCED_TYPENAME boost::enable_if_c<
106
                enable_binary_hash<Float, 24, 128>::value,
107
                std::size_t>::type)
108
0
        {
109
0
            return hash_binary((char*) &v, 4);
110
0
        }
111
112
113
        template <typename Float>
114
        inline std::size_t float_hash_impl(Float v,
115
            BOOST_DEDUCED_TYPENAME boost::enable_if_c<
116
                enable_binary_hash<Float, 53, 1024>::value,
117
                std::size_t>::type)
118
0
        {
119
0
            return hash_binary((char*) &v, 8);
120
0
        }
Unexecuted instantiation: _ZN5boost11hash_detail15float_hash_implIdEEmT_NS_11enable_if_cIXsr18enable_binary_hashIS2_XLi53EEXLi1024EEEE5valueEmE4typeE
Unexecuted instantiation: _ZN5boost11hash_detail15float_hash_implIeEEmT_NS_11enable_if_cIXsr18enable_binary_hashIS2_XLi53EEXLi1024EEEE5valueEmE4typeE
121
122
        template <typename Float>
123
        inline std::size_t float_hash_impl(Float v,
124
            BOOST_DEDUCED_TYPENAME boost::enable_if_c<
125
                enable_binary_hash<Float, 64, 16384>::value,
126
                std::size_t>::type)
127
        {
128
            return hash_binary((char*) &v, 10);
129
        }
130
131
        template <typename Float>
132
        inline std::size_t float_hash_impl(Float v,
133
            BOOST_DEDUCED_TYPENAME boost::enable_if_c<
134
                enable_binary_hash<Float, 113, 16384>::value,
135
                std::size_t>::type)
136
        {
137
            return hash_binary((char*) &v, 16);
138
        }
139
140
        ////////////////////////////////////////////////////////////////////////
141
        // Portable hash function
142
        //
143
        // Used as a fallback when the binary hash function isn't supported.
144
145
        template <class T>
146
        inline std::size_t float_hash_impl2(T v)
147
        {
148
            boost::hash_detail::call_frexp<T> frexp;
149
            boost::hash_detail::call_ldexp<T> ldexp;
150
151
            int exp = 0;
152
153
            v = frexp(v, &exp);
154
155
            // A postive value is easier to hash, so combine the
156
            // sign with the exponent and use the absolute value.
157
            if(v < 0) {
158
                v = -v;
159
                exp += limits<T>::max_exponent -
160
                    limits<T>::min_exponent;
161
            }
162
163
            v = ldexp(v, limits<std::size_t>::digits);
164
            std::size_t seed = static_cast<std::size_t>(v);
165
            v -= static_cast<T>(seed);
166
167
            // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
168
            std::size_t const length
169
                = (limits<T>::digits *
170
                        boost::static_log2<limits<T>::radix>::value
171
                        + limits<std::size_t>::digits - 1)
172
                / limits<std::size_t>::digits;
173
174
            for(std::size_t i = 0; i != length; ++i)
175
            {
176
                v = ldexp(v, limits<std::size_t>::digits);
177
                std::size_t part = static_cast<std::size_t>(v);
178
                v -= static_cast<T>(part);
179
                hash_float_combine(seed, part);
180
            }
181
182
            hash_float_combine(seed, static_cast<std::size_t>(exp));
183
184
            return seed;
185
        }
186
187
#if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
188
        template <class T>
189
        inline std::size_t float_hash_impl(T v, ...)
190
        {
191
            typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
192
            return float_hash_impl2(static_cast<type>(v));
193
        }
194
#endif
195
    }
196
}
197
198
#if BOOST_HASH_USE_FPCLASSIFY
199
200
#include <boost/config/no_tr1/cmath.hpp>
201
202
namespace boost
203
{
204
    namespace hash_detail
205
    {
206
        template <class T>
207
        inline std::size_t float_hash_value(T v)
208
        {
209
#if defined(fpclassify)
210
            switch (fpclassify(v))
211
#elif BOOST_HASH_CONFORMANT_FLOATS
212
            switch (std::fpclassify(v))
213
#else
214
            using namespace std;
215
            switch (fpclassify(v))
216
#endif
217
            {
218
            case FP_ZERO:
219
                return 0;
220
            case FP_INFINITE:
221
                return (std::size_t)(v > 0 ? -1 : -2);
222
            case FP_NAN:
223
                return (std::size_t)(-3);
224
            case FP_NORMAL:
225
            case FP_SUBNORMAL:
226
                return float_hash_impl(v, 0);
227
            default:
228
                BOOST_ASSERT(0);
229
                return 0;
230
            }
231
        }
232
    }
233
}
234
235
#else // !BOOST_HASH_USE_FPCLASSIFY
236
237
namespace boost
238
{
239
    namespace hash_detail
240
    {
241
        template <class T>
242
        inline bool is_zero(T v)
243
0
        {
244
0
#if !defined(__GNUC__) && !defined(__clang__)
245
0
            return v == 0;
246
0
#else
247
0
            // GCC's '-Wfloat-equal' will complain about comparing
248
0
            // v to 0, but because it disables warnings for system
249
0
            // headers it won't complain if you use std::equal_to to
250
0
            // compare with 0. Resulting in this silliness:
251
0
            return std::equal_to<T>()(v, 0);
252
0
#endif
253
0
        }
Unexecuted instantiation: _ZN5boost11hash_detail7is_zeroIfEEbT_
Unexecuted instantiation: _ZN5boost11hash_detail7is_zeroIdEEbT_
Unexecuted instantiation: _ZN5boost11hash_detail7is_zeroIeEEbT_
254
255
        template <class T>
256
        inline std::size_t float_hash_value(T v)
257
0
        {
258
0
            return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
259
0
        }
Unexecuted instantiation: _ZN5boost11hash_detail16float_hash_valueIfEEmT_
Unexecuted instantiation: _ZN5boost11hash_detail16float_hash_valueIdEEmT_
Unexecuted instantiation: _ZN5boost11hash_detail16float_hash_valueIeEEmT_
260
    }
261
}
262
263
#endif // BOOST_HASH_USE_FPCLASSIFY
264
265
#undef BOOST_HASH_USE_FPCLASSIFY
266
267
#if defined(BOOST_MSVC)
268
#pragma warning(pop)
269
#endif
270
271
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/container_hash/hash.hpp
Line
Count
Source (jump to first uncovered line)
1
2
// Copyright 2005-2014 Daniel James.
3
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6
//  Based on Peter Dimov's proposal
7
//  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
8
//  issue 6.18.
9
//
10
//  This also contains public domain code from MurmurHash. From the
11
//  MurmurHash header:
12
13
// MurmurHash3 was written by Austin Appleby, and is placed in the public
14
// domain. The author hereby disclaims copyright to this source code.
15
16
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
17
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
18
19
#include <boost/container_hash/hash_fwd.hpp>
20
#include <functional>
21
#include <iterator>
22
#include <boost/container_hash/detail/hash_float.hpp>
23
#include <string>
24
#include <boost/limits.hpp>
25
#include <boost/type_traits/is_enum.hpp>
26
#include <boost/type_traits/is_integral.hpp>
27
#include <boost/core/enable_if.hpp>
28
#include <boost/cstdint.hpp>
29
30
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
31
#include <boost/type_traits/is_pointer.hpp>
32
#endif
33
34
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
35
#include <typeindex>
36
#endif
37
38
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
39
#include <system_error>
40
#endif
41
42
#if defined(BOOST_MSVC)
43
#pragma warning(push)
44
45
#if BOOST_MSVC >= 1400
46
#pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values
47
                              // are always of range '0' to '4294967295'.
48
                              // Loop executes infinitely.
49
#endif
50
51
#endif
52
53
#if BOOST_WORKAROUND(__GNUC__, < 3) \
54
    && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
55
#define BOOST_HASH_CHAR_TRAITS string_char_traits
56
#else
57
#define BOOST_HASH_CHAR_TRAITS char_traits
58
#endif
59
60
#if defined(_MSC_VER)
61
#   define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r)
62
#else
63
#   define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
64
#endif
65
66
// Detect whether standard library has C++17 headers
67
68
#if !defined(BOOST_HASH_CXX17)
69
#   if defined(BOOST_MSVC)
70
#       if defined(_HAS_CXX17) && _HAS_CXX17
71
#           define BOOST_HASH_CXX17 1
72
#       endif
73
#   elif defined(__cplusplus) && __cplusplus >= 201703
74
#       define BOOST_HASH_CXX17 1
75
#   endif
76
#endif
77
78
#if !defined(BOOST_HASH_CXX17)
79
#   define BOOST_HASH_CXX17 0
80
#endif
81
82
#if BOOST_HASH_CXX17 && defined(__has_include)
83
#   if !defined(BOOST_HASH_HAS_STRING_VIEW) && __has_include(<string_view>)
84
#       define BOOST_HASH_HAS_STRING_VIEW 1
85
#   endif
86
#   if !defined(BOOST_HASH_HAS_OPTIONAL) && __has_include(<optional>)
87
#       define BOOST_HASH_HAS_OPTIONAL 1
88
#   endif
89
#   if !defined(BOOST_HASH_HAS_VARIANT) && __has_include(<variant>)
90
#       define BOOST_HASH_HAS_VARIANT 1
91
#   endif
92
#endif
93
94
#if !defined(BOOST_HASH_HAS_STRING_VIEW)
95
#   define BOOST_HASH_HAS_STRING_VIEW 0
96
#endif
97
98
#if !defined(BOOST_HASH_HAS_OPTIONAL)
99
#   define BOOST_HASH_HAS_OPTIONAL 0
100
#endif
101
102
#if !defined(BOOST_HASH_HAS_VARIANT)
103
#   define BOOST_HASH_HAS_VARIANT 0
104
#endif
105
106
#if BOOST_HASH_HAS_STRING_VIEW
107
#   include <string_view>
108
#endif
109
110
#if BOOST_HASH_HAS_OPTIONAL
111
#   include <optional>
112
#endif
113
114
#if BOOST_HASH_HAS_VARIANT
115
#   include <variant>
116
#endif
117
118
namespace boost
119
{
120
    namespace hash_detail
121
    {
122
#if defined(BOOST_NO_CXX98_FUNCTION_BASE)
123
        template <typename T>
124
        struct hash_base
125
        {
126
            typedef T argument_type;
127
            typedef std::size_t result_type;
128
        };
129
#else
130
        template <typename T>
131
        struct hash_base : std::unary_function<T, std::size_t> {};
132
#endif
133
134
        struct enable_hash_value { typedef std::size_t type; };
135
136
        template <typename T> struct basic_numbers {};
137
        template <typename T> struct long_numbers;
138
        template <typename T> struct ulong_numbers;
139
        template <typename T> struct float_numbers {};
140
141
        template <> struct basic_numbers<bool> :
142
            boost::hash_detail::enable_hash_value {};
143
        template <> struct basic_numbers<char> :
144
            boost::hash_detail::enable_hash_value {};
145
        template <> struct basic_numbers<unsigned char> :
146
            boost::hash_detail::enable_hash_value {};
147
        template <> struct basic_numbers<signed char> :
148
            boost::hash_detail::enable_hash_value {};
149
        template <> struct basic_numbers<short> :
150
            boost::hash_detail::enable_hash_value {};
151
        template <> struct basic_numbers<unsigned short> :
152
            boost::hash_detail::enable_hash_value {};
153
        template <> struct basic_numbers<int> :
154
            boost::hash_detail::enable_hash_value {};
155
        template <> struct basic_numbers<unsigned int> :
156
            boost::hash_detail::enable_hash_value {};
157
        template <> struct basic_numbers<long> :
158
            boost::hash_detail::enable_hash_value {};
159
        template <> struct basic_numbers<unsigned long> :
160
            boost::hash_detail::enable_hash_value {};
161
162
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
163
        template <> struct basic_numbers<wchar_t> :
164
            boost::hash_detail::enable_hash_value {};
165
#endif
166
167
#if !defined(BOOST_NO_CXX11_CHAR16_T)
168
        template <> struct basic_numbers<char16_t> :
169
            boost::hash_detail::enable_hash_value {};
170
#endif
171
172
#if !defined(BOOST_NO_CXX11_CHAR32_T)
173
        template <> struct basic_numbers<char32_t> :
174
            boost::hash_detail::enable_hash_value {};
175
#endif
176
177
        // long_numbers is defined like this to allow for separate
178
        // specialization for long_long and int128_type, in case
179
        // they conflict.
180
        template <typename T> struct long_numbers2 {};
181
        template <typename T> struct ulong_numbers2 {};
182
        template <typename T> struct long_numbers : long_numbers2<T> {};
183
        template <typename T> struct ulong_numbers : ulong_numbers2<T> {};
184
185
#if !defined(BOOST_NO_LONG_LONG)
186
        template <> struct long_numbers<boost::long_long_type> :
187
            boost::hash_detail::enable_hash_value {};
188
        template <> struct ulong_numbers<boost::ulong_long_type> :
189
            boost::hash_detail::enable_hash_value {};
190
#endif
191
192
#if defined(BOOST_HAS_INT128)
193
        template <> struct long_numbers2<boost::int128_type> :
194
            boost::hash_detail::enable_hash_value {};
195
        template <> struct ulong_numbers2<boost::uint128_type> :
196
            boost::hash_detail::enable_hash_value {};
197
#endif
198
199
        template <> struct float_numbers<float> :
200
            boost::hash_detail::enable_hash_value {};
201
        template <> struct float_numbers<double> :
202
            boost::hash_detail::enable_hash_value {};
203
        template <> struct float_numbers<long double> :
204
            boost::hash_detail::enable_hash_value {};
205
    }
206
207
    template <typename T>
208
    typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
209
    template <typename T>
210
    typename boost::hash_detail::long_numbers<T>::type hash_value(T);
211
    template <typename T>
212
    typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
213
214
    template <typename T>
215
    typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
216
        hash_value(T);
217
218
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
219
    template <class T> std::size_t hash_value(T* const&);
220
#else
221
    template <class T> std::size_t hash_value(T*);
222
#endif
223
224
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
225
    template< class T, unsigned N >
226
    std::size_t hash_value(const T (&x)[N]);
227
228
    template< class T, unsigned N >
229
    std::size_t hash_value(T (&x)[N]);
230
#endif
231
232
    template <class Ch, class A>
233
    std::size_t hash_value(
234
        std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
235
236
#if BOOST_HASH_HAS_STRING_VIEW
237
    template <class Ch>
238
    std::size_t hash_value(
239
        std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const&);
240
#endif
241
242
    template <typename T>
243
    typename boost::hash_detail::float_numbers<T>::type hash_value(T);
244
245
#if BOOST_HASH_HAS_OPTIONAL
246
    template <typename T>
247
    std::size_t hash_value(std::optional<T> const&);
248
#endif
249
250
#if BOOST_HASH_HAS_VARIANT
251
    std::size_t hash_value(std::monostate);
252
    template <typename... Types>
253
    std::size_t hash_value(std::variant<Types...> const&);
254
#endif
255
256
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
257
    std::size_t hash_value(std::type_index);
258
#endif
259
260
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
261
    std::size_t hash_value(std::error_code const&);
262
    std::size_t hash_value(std::error_condition const&);
263
#endif
264
265
    // Implementation
266
267
    namespace hash_detail
268
    {
269
        template <class T>
270
        inline std::size_t hash_value_signed(T val)
271
0
        {
272
0
             const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits;
273
0
             // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
274
0
             const int length = (std::numeric_limits<T>::digits - 1)
275
0
                 / static_cast<int>(size_t_bits);
276
0
277
0
             std::size_t seed = 0;
278
0
             T positive = val < 0 ? -1 - val : val;
279
0
280
0
             // Hopefully, this loop can be unrolled.
281
0
             for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
282
0
             {
283
0
                 seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
284
0
             }
285
0
             seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
286
0
287
0
             return seed;
288
0
        }
Unexecuted instantiation: _ZN5boost11hash_detail17hash_value_signedIxEEmT_
Unexecuted instantiation: _ZN5boost11hash_detail17hash_value_signedInEEmT_
289
290
        template <class T>
291
        inline std::size_t hash_value_unsigned(T val)
292
0
        {
293
0
             const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits;
294
0
             // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
295
0
             const int length = (std::numeric_limits<T>::digits - 1)
296
0
                 / static_cast<int>(size_t_bits);
297
0
298
0
             std::size_t seed = 0;
299
0
300
0
             // Hopefully, this loop can be unrolled.
301
0
             for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
302
0
             {
303
0
                 seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
304
0
             }
305
0
             seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
306
0
307
0
             return seed;
308
0
        }
Unexecuted instantiation: _ZN5boost11hash_detail19hash_value_unsignedIyEEmT_
Unexecuted instantiation: _ZN5boost11hash_detail19hash_value_unsignedIoEEmT_
309
310
        template <typename SizeT>
311
        inline void hash_combine_impl(SizeT& seed, SizeT value)
312
0
        {
313
0
            seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
314
0
        }
315
316
        inline void hash_combine_impl(boost::uint32_t& h1,
317
                boost::uint32_t k1)
318
0
        {
319
0
            const uint32_t c1 = 0xcc9e2d51;
320
0
            const uint32_t c2 = 0x1b873593;
321
0
322
0
            k1 *= c1;
323
0
            k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15);
324
0
            k1 *= c2;
325
0
326
0
            h1 ^= k1;
327
0
            h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13);
328
0
            h1 = h1*5+0xe6546b64;
329
0
        }
330
331
332
// Don't define 64-bit hash combine on platforms without 64 bit integers,
333
// and also not for 32-bit gcc as it warns about the 64-bit constant.
334
#if !defined(BOOST_NO_INT64_T) && \
335
        !(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
336
337
        inline void hash_combine_impl(boost::uint64_t& h,
338
                boost::uint64_t k)
339
0
        {
340
0
            const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
341
0
            const int r = 47;
342
0
343
0
            k *= m;
344
0
            k ^= k >> r;
345
0
            k *= m;
346
0
347
0
            h ^= k;
348
0
            h *= m;
349
0
350
0
            // Completely arbitrary number, to prevent 0's
351
0
            // from hashing to 0.
352
0
            h += 0xe6546b64;
353
0
        }
354
355
#endif // BOOST_NO_INT64_T
356
    }
357
358
    template <typename T>
359
    typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
360
0
    {
361
0
        return static_cast<std::size_t>(v);
362
0
    }
Unexecuted instantiation: _ZN5boost10hash_valueIbEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIcEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIaEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIhEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIwEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIDsEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIDiEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIsEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueItEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIiEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIjEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIlEENS_11hash_detail13basic_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueImEENS_11hash_detail13basic_numbersIT_E4typeES3_
363
364
    template <typename T>
365
    typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
366
0
    {
367
0
        return hash_detail::hash_value_signed(v);
368
0
    }
Unexecuted instantiation: _ZN5boost10hash_valueIxEENS_11hash_detail12long_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueInEENS_11hash_detail12long_numbersIT_E4typeES3_
369
370
    template <typename T>
371
    typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
372
0
    {
373
0
        return hash_detail::hash_value_unsigned(v);
374
0
    }
Unexecuted instantiation: _ZN5boost10hash_valueIyEENS_11hash_detail13ulong_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIoEENS_11hash_detail13ulong_numbersIT_E4typeES3_
375
376
    template <typename T>
377
    typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
378
        hash_value(T v)
379
    {
380
        return static_cast<std::size_t>(v);
381
    }
382
383
    // Implementation by Alberto Barbati and Dave Harris.
384
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
385
    template <class T> std::size_t hash_value(T* const& v)
386
#else
387
    template <class T> std::size_t hash_value(T* v)
388
#endif
389
0
    {
390
0
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
391
0
    // for some reason ptrdiff_t on OpenVMS compiler with
392
0
    // 64 bit is not 64 bit !!!
393
0
        std::size_t x = static_cast<std::size_t>(
394
0
           reinterpret_cast<long long int>(v));
395
0
#else
396
0
        std::size_t x = static_cast<std::size_t>(
397
0
           reinterpret_cast<std::ptrdiff_t>(v));
398
0
#endif
399
0
        return x + (x >> 3);
400
0
    }
401
402
#if defined(BOOST_MSVC)
403
#pragma warning(push)
404
#if BOOST_MSVC <= 1400
405
#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
406
                              // 'unsigned int', possible loss of data
407
                              // A misguided attempt to detect 64-bit
408
                              // incompatability.
409
#endif
410
#endif
411
412
    template <class T>
413
    inline void hash_combine(std::size_t& seed, T const& v)
414
0
    {
415
0
        boost::hash<T> hasher;
416
0
        return boost::hash_detail::hash_combine_impl(seed, hasher(v));
417
0
    }
Unexecuted instantiation: _ZN5boost12hash_combineIiEEvRmRKT_
Unexecuted instantiation: _ZN5boost12hash_combineIPKNSt3__114error_categoryEEEvRmRKT_
Unexecuted instantiation: _ZN5boost12hash_combineIcEEvRmRKT_
Unexecuted instantiation: _ZN5boost12hash_combineIwEEvRmRKT_
Unexecuted instantiation: _ZN5boost12hash_combineIDsEEvRmRKT_
Unexecuted instantiation: _ZN5boost12hash_combineIDiEEvRmRKT_
418
419
#if defined(BOOST_MSVC)
420
#pragma warning(pop)
421
#endif
422
423
    template <class It>
424
    inline std::size_t hash_range(It first, It last)
425
0
    {
426
0
        std::size_t seed = 0;
427
0
428
0
        for(; first != last; ++first)
429
0
        {
430
0
            hash_combine<typename std::iterator_traits<It>::value_type>(seed, *first);
431
0
        }
432
0
433
0
        return seed;
434
0
    }
Unexecuted instantiation: _ZN5boost10hash_rangeINSt3__111__wrap_iterIPKcEEEEmT_S6_
Unexecuted instantiation: _ZN5boost10hash_rangeINSt3__111__wrap_iterIPKwEEEEmT_S6_
Unexecuted instantiation: _ZN5boost10hash_rangeINSt3__111__wrap_iterIPKDsEEEEmT_S6_
Unexecuted instantiation: _ZN5boost10hash_rangeINSt3__111__wrap_iterIPKDiEEEEmT_S6_
Unexecuted instantiation: _ZN5boost10hash_rangeIPKwEEmT_S3_
Unexecuted instantiation: _ZN5boost10hash_rangeIPKDsEEmT_S3_
Unexecuted instantiation: _ZN5boost10hash_rangeIPKDiEEmT_S3_
Unexecuted instantiation: _ZN5boost10hash_rangeIPKcEEmT_S3_
435
436
    template <class It>
437
    inline void hash_range(std::size_t& seed, It first, It last)
438
    {
439
        for(; first != last; ++first)
440
        {
441
            hash_combine<typename std::iterator_traits<It>::value_type>(seed, *first);
442
        }
443
    }
444
445
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
446
    template <class T>
447
    inline std::size_t hash_range(T* first, T* last)
448
    {
449
        std::size_t seed = 0;
450
451
        for(; first != last; ++first)
452
        {
453
            boost::hash<T> hasher;
454
            seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
455
        }
456
457
        return seed;
458
    }
459
460
    template <class T>
461
    inline void hash_range(std::size_t& seed, T* first, T* last)
462
    {
463
        for(; first != last; ++first)
464
        {
465
            boost::hash<T> hasher;
466
            seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
467
        }
468
    }
469
#endif
470
471
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
472
    template< class T, unsigned N >
473
    inline std::size_t hash_value(const T (&x)[N])
474
    {
475
        return hash_range(x, x + N);
476
    }
477
478
    template< class T, unsigned N >
479
    inline std::size_t hash_value(T (&x)[N])
480
    {
481
        return hash_range(x, x + N);
482
    }
483
#endif
484
485
    template <class Ch, class A>
486
    inline std::size_t hash_value(
487
        std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
488
0
    {
489
0
        return hash_range(v.begin(), v.end());
490
0
    }
Unexecuted instantiation: _ZN5boost10hash_valueIcNSt3__19allocatorIcEEEEmRKNS1_12basic_stringIT_NS1_11char_traitsIS5_EET0_EE
Unexecuted instantiation: _ZN5boost10hash_valueIwNSt3__19allocatorIwEEEEmRKNS1_12basic_stringIT_NS1_11char_traitsIS5_EET0_EE
Unexecuted instantiation: _ZN5boost10hash_valueIDsNSt3__19allocatorIDsEEEEmRKNS1_12basic_stringIT_NS1_11char_traitsIS5_EET0_EE
Unexecuted instantiation: _ZN5boost10hash_valueIDiNSt3__19allocatorIDiEEEEmRKNS1_12basic_stringIT_NS1_11char_traitsIS5_EET0_EE
491
492
#if BOOST_HASH_HAS_STRING_VIEW
493
    template <class Ch>
494
    inline std::size_t hash_value(
495
        std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const& v)
496
0
    {
497
0
        return hash_range(v.begin(), v.end());
498
0
    }
Unexecuted instantiation: _ZN5boost10hash_valueIcEEmRKNSt3__117basic_string_viewIT_NS1_11char_traitsIS3_EEEE
Unexecuted instantiation: _ZN5boost10hash_valueIwEEmRKNSt3__117basic_string_viewIT_NS1_11char_traitsIS3_EEEE
Unexecuted instantiation: _ZN5boost10hash_valueIDsEEmRKNSt3__117basic_string_viewIT_NS1_11char_traitsIS3_EEEE
Unexecuted instantiation: _ZN5boost10hash_valueIDiEEmRKNSt3__117basic_string_viewIT_NS1_11char_traitsIS3_EEEE
499
#endif
500
501
    template <typename T>
502
    typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
503
0
    {
504
0
        return boost::hash_detail::float_hash_value(v);
505
0
    }
Unexecuted instantiation: _ZN5boost10hash_valueIfEENS_11hash_detail13float_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIdEENS_11hash_detail13float_numbersIT_E4typeES3_
Unexecuted instantiation: _ZN5boost10hash_valueIeEENS_11hash_detail13float_numbersIT_E4typeES3_
506
507
#if BOOST_HASH_HAS_OPTIONAL
508
    template <typename T>
509
    inline std::size_t hash_value(std::optional<T> const& v) {
510
        if (!v) {
511
            // Arbitray value for empty optional.
512
            return 0x12345678;
513
        } else {
514
            boost::hash<T> hf;
515
            return hf(*v);
516
        }
517
    }
518
#endif
519
520
#if BOOST_HASH_HAS_VARIANT
521
0
    inline std::size_t hash_value(std::monostate) {
522
0
        return 0x87654321;
523
0
    }
524
525
    template <typename... Types>
526
    inline std::size_t hash_value(std::variant<Types...> const& v) {
527
        std::size_t seed = 0;
528
        hash_combine(seed, v.index());
529
        std::visit([&seed](auto&& x) { hash_combine(seed, x); }, v);
530
        return seed;
531
    }
532
#endif
533
534
535
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
536
    inline std::size_t hash_value(std::type_index v)
537
0
    {
538
0
        return v.hash_code();
539
0
    }
540
#endif
541
542
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
543
0
    inline std::size_t hash_value(std::error_code const& v) {
544
0
        std::size_t seed = 0;
545
0
        hash_combine(seed, v.value());
546
0
        hash_combine(seed, &v.category());
547
0
        return seed;
548
0
    }
549
550
0
    inline std::size_t hash_value(std::error_condition const& v) {
551
0
        std::size_t seed = 0;
552
0
        hash_combine(seed, v.value());
553
0
        hash_combine(seed, &v.category());
554
0
        return seed;
555
0
    }
556
#endif
557
558
    //
559
    // boost::hash
560
    //
561
562
    // Define the specializations required by the standard. The general purpose
563
    // boost::hash is defined later in extensions.hpp if
564
    // BOOST_HASH_NO_EXTENSIONS is not defined.
565
566
    // BOOST_HASH_SPECIALIZE - define a specialization for a type which is
567
    // passed by copy.
568
    //
569
    // BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
570
    // passed by const reference.
571
    //
572
    // These are undefined later.
573
574
#define BOOST_HASH_SPECIALIZE(type) \
575
    template <> struct hash<type> \
576
         : public boost::hash_detail::hash_base<type> \
577
    { \
578
        std::size_t operator()(type v) const \
579
0
        { \
580
0
            return boost::hash_value(v); \
581
0
        } \
Unexecuted instantiation: _ZNK5boost4hashIbEclEb
Unexecuted instantiation: _ZNK5boost4hashIcEclEc
Unexecuted instantiation: _ZNK5boost4hashIaEclEa
Unexecuted instantiation: _ZNK5boost4hashIhEclEh
Unexecuted instantiation: _ZNK5boost4hashIwEclEw
Unexecuted instantiation: _ZNK5boost4hashIDsEclEDs
Unexecuted instantiation: _ZNK5boost4hashIDiEclEDi
Unexecuted instantiation: _ZNK5boost4hashIsEclEs
Unexecuted instantiation: _ZNK5boost4hashItEclEt
Unexecuted instantiation: _ZNK5boost4hashIiEclEi
Unexecuted instantiation: _ZNK5boost4hashIjEclEj
Unexecuted instantiation: _ZNK5boost4hashIlEclEl
Unexecuted instantiation: _ZNK5boost4hashImEclEm
Unexecuted instantiation: _ZNK5boost4hashIfEclEf
Unexecuted instantiation: _ZNK5boost4hashIdEclEd
Unexecuted instantiation: _ZNK5boost4hashIeEclEe
Unexecuted instantiation: _ZNK5boost4hashIxEclEx
Unexecuted instantiation: _ZNK5boost4hashIyEclEy
Unexecuted instantiation: _ZNK5boost4hashInEclEn
Unexecuted instantiation: _ZNK5boost4hashIoEclEo
Unexecuted instantiation: _ZNK5boost4hashINSt3__110type_indexEEclES2_
582
    };
583
584
#define BOOST_HASH_SPECIALIZE_REF(type) \
585
    template <> struct hash<type> \
586
         : public boost::hash_detail::hash_base<type> \
587
    { \
588
        std::size_t operator()(type const& v) const \
589
0
        { \
590
0
            return boost::hash_value(v); \
591
0
        } \
Unexecuted instantiation: _ZNK5boost4hashINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEclERKS7_
Unexecuted instantiation: _ZNK5boost4hashINSt3__112basic_stringIwNS1_11char_traitsIwEENS1_9allocatorIwEEEEEclERKS7_
Unexecuted instantiation: _ZNK5boost4hashINSt3__112basic_stringIDsNS1_11char_traitsIDsEENS1_9allocatorIDsEEEEEclERKS7_
Unexecuted instantiation: _ZNK5boost4hashINSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEEEclERKS7_
Unexecuted instantiation: _ZNK5boost4hashINSt3__117basic_string_viewIcNS1_11char_traitsIcEEEEEclERKS5_
Unexecuted instantiation: _ZNK5boost4hashINSt3__117basic_string_viewIwNS1_11char_traitsIwEEEEEclERKS5_
Unexecuted instantiation: _ZNK5boost4hashINSt3__117basic_string_viewIDsNS1_11char_traitsIDsEEEEEclERKS5_
Unexecuted instantiation: _ZNK5boost4hashINSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEEEclERKS5_
592
    };
593
594
#define BOOST_HASH_SPECIALIZE_TEMPLATE_REF(type) \
595
    struct hash<type> \
596
         : public boost::hash_detail::hash_base<type> \
597
    { \
598
        std::size_t operator()(type const& v) const \
599
        { \
600
            return boost::hash_value(v); \
601
        } \
602
    };
603
604
    BOOST_HASH_SPECIALIZE(bool)
605
    BOOST_HASH_SPECIALIZE(char)
606
    BOOST_HASH_SPECIALIZE(signed char)
607
    BOOST_HASH_SPECIALIZE(unsigned char)
608
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
609
    BOOST_HASH_SPECIALIZE(wchar_t)
610
#endif
611
#if !defined(BOOST_NO_CXX11_CHAR16_T)
612
    BOOST_HASH_SPECIALIZE(char16_t)
613
#endif
614
#if !defined(BOOST_NO_CXX11_CHAR32_T)
615
    BOOST_HASH_SPECIALIZE(char32_t)
616
#endif
617
    BOOST_HASH_SPECIALIZE(short)
618
    BOOST_HASH_SPECIALIZE(unsigned short)
619
    BOOST_HASH_SPECIALIZE(int)
620
    BOOST_HASH_SPECIALIZE(unsigned int)
621
    BOOST_HASH_SPECIALIZE(long)
622
    BOOST_HASH_SPECIALIZE(unsigned long)
623
624
    BOOST_HASH_SPECIALIZE(float)
625
    BOOST_HASH_SPECIALIZE(double)
626
    BOOST_HASH_SPECIALIZE(long double)
627
628
    BOOST_HASH_SPECIALIZE_REF(std::string)
629
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
630
    BOOST_HASH_SPECIALIZE_REF(std::wstring)
631
#endif
632
#if !defined(BOOST_NO_CXX11_CHAR16_T)
633
    BOOST_HASH_SPECIALIZE_REF(std::basic_string<char16_t>)
634
#endif
635
#if !defined(BOOST_NO_CXX11_CHAR32_T)
636
    BOOST_HASH_SPECIALIZE_REF(std::basic_string<char32_t>)
637
#endif
638
639
#if BOOST_HASH_HAS_STRING_VIEW
640
    BOOST_HASH_SPECIALIZE_REF(std::string_view)
641
#   if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
642
    BOOST_HASH_SPECIALIZE_REF(std::wstring_view)
643
#   endif
644
#   if !defined(BOOST_NO_CXX11_CHAR16_T)
645
    BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char16_t>)
646
#   endif
647
#   if !defined(BOOST_NO_CXX11_CHAR32_T)
648
    BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char32_t>)
649
#   endif
650
#endif
651
652
#if !defined(BOOST_NO_LONG_LONG)
653
    BOOST_HASH_SPECIALIZE(boost::long_long_type)
654
    BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
655
#endif
656
657
#if defined(BOOST_HAS_INT128)
658
    BOOST_HASH_SPECIALIZE(boost::int128_type)
659
    BOOST_HASH_SPECIALIZE(boost::uint128_type)
660
#endif
661
662
#if BOOST_HASH_HAS_OPTIONAL
663
    template <typename T>
664
    BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::optional<T>)
665
#endif
666
667
#if !defined(BOOST_HASH_HAS_VARIANT)
668
    template <typename... T>
669
    BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::variant<T...>)
670
    BOOST_HASH_SPECIALIZE(std::monostate)
671
#endif
672
673
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
674
    BOOST_HASH_SPECIALIZE(std::type_index)
675
#endif
676
677
#undef BOOST_HASH_SPECIALIZE
678
#undef BOOST_HASH_SPECIALIZE_REF
679
#undef BOOST_HASH_SPECIALIZE_TEMPLATE_REF
680
681
// Specializing boost::hash for pointers.
682
683
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
684
685
    template <class T>
686
    struct hash<T*>
687
        : public boost::hash_detail::hash_base<T*>
688
    {
689
        std::size_t operator()(T* v) const
690
0
        {
691
0
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
692
0
            return boost::hash_value(v);
693
0
#else
694
0
            std::size_t x = static_cast<std::size_t>(
695
0
                reinterpret_cast<std::ptrdiff_t>(v));
696
0
697
0
            return x + (x >> 3);
698
0
#endif
699
0
        }
700
    };
701
702
#else
703
704
    // For compilers without partial specialization, we define a
705
    // boost::hash for all remaining types. But hash_impl is only defined
706
    // for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
707
    // is defined there will still be a compile error for types not supported
708
    // in the standard.
709
710
    namespace hash_detail
711
    {
712
        template <bool IsPointer>
713
        struct hash_impl;
714
715
        template <>
716
        struct hash_impl<true>
717
        {
718
            template <class T>
719
            struct inner
720
                : public boost::hash_detail::hash_base<T>
721
            {
722
                std::size_t operator()(T val) const
723
                {
724
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
725
                    return boost::hash_value(val);
726
#else
727
                    std::size_t x = static_cast<std::size_t>(
728
                        reinterpret_cast<std::ptrdiff_t>(val));
729
730
                    return x + (x >> 3);
731
#endif
732
                }
733
            };
734
        };
735
    }
736
737
    template <class T> struct hash
738
        : public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
739
            ::BOOST_NESTED_TEMPLATE inner<T>
740
    {
741
    };
742
743
#endif
744
}
745
746
#undef BOOST_HASH_CHAR_TRAITS
747
#undef BOOST_FUNCTIONAL_HASH_ROTL32
748
749
#if defined(BOOST_MSVC)
750
#pragma warning(pop)
751
#endif
752
753
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
754
755
// Include this outside of the include guards in case the file is included
756
// twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it
757
// undefined.
758
759
#if !defined(BOOST_HASH_NO_EXTENSIONS) \
760
    && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
761
#include <boost/container_hash/extensions.hpp>
762
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/core/addressof.hpp
Line
Count
Source
1
/*
2
Copyright (C) 2002 Brad King (brad.king@kitware.com)
3
                   Douglas Gregor (gregod@cs.rpi.edu)
4
5
Copyright (C) 2002, 2008, 2013 Peter Dimov
6
7
Copyright (C) 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
8
9
Distributed under the Boost Software License, Version 1.0.
10
(See accompanying file LICENSE_1_0.txt or copy at
11
http://www.boost.org/LICENSE_1_0.txt)
12
*/
13
14
#ifndef BOOST_CORE_ADDRESSOF_HPP
15
#define BOOST_CORE_ADDRESSOF_HPP
16
17
#include <boost/config.hpp>
18
19
#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215
20
#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
21
#elif defined(BOOST_GCC) && BOOST_GCC >= 70000
22
#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
23
#elif defined(__has_builtin)
24
#if __has_builtin(__builtin_addressof)
25
#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
26
#endif
27
#endif
28
29
#if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF)
30
#if defined(BOOST_NO_CXX11_CONSTEXPR)
31
#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
32
#endif
33
34
namespace boost {
35
36
template<class T>
37
BOOST_CONSTEXPR inline T*
38
addressof(T& o) BOOST_NOEXCEPT
39
6
{
40
6
    return __builtin_addressof(o);
41
6
}
42
43
} /* boost */
44
#else
45
#include <boost/config/workaround.hpp>
46
#include <cstddef>
47
48
namespace boost {
49
namespace detail {
50
51
template<class T>
52
class addrof_ref {
53
public:
54
    BOOST_FORCEINLINE addrof_ref(T& o) BOOST_NOEXCEPT
55
        : o_(o) { }
56
    BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT {
57
        return o_;
58
    }
59
private:
60
    addrof_ref& operator=(const addrof_ref&);
61
    T& o_;
62
};
63
64
template<class T>
65
struct addrof {
66
    static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT {
67
        return reinterpret_cast<T*>(&
68
            const_cast<char&>(reinterpret_cast<const volatile char&>(o)));
69
    }
70
    static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT {
71
        return p;
72
    }
73
};
74
75
#if !defined(BOOST_NO_CXX11_NULLPTR)
76
#if !defined(BOOST_NO_CXX11_DECLTYPE) && \
77
    (defined(__INTEL_COMPILER) || \
78
        (defined(__clang__) && !defined(_LIBCPP_VERSION)))
79
typedef decltype(nullptr) addrof_null_t;
80
#else
81
typedef std::nullptr_t addrof_null_t;
82
#endif
83
84
template<>
85
struct addrof<addrof_null_t> {
86
    typedef addrof_null_t type;
87
    static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
88
        return &o;
89
    }
90
};
91
92
template<>
93
struct addrof<const addrof_null_t> {
94
    typedef const addrof_null_t type;
95
    static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
96
        return &o;
97
    }
98
};
99
100
template<>
101
struct addrof<volatile addrof_null_t> {
102
    typedef volatile addrof_null_t type;
103
    static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
104
        return &o;
105
    }
106
};
107
108
template<>
109
struct addrof<const volatile addrof_null_t> {
110
    typedef const volatile addrof_null_t type;
111
    static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
112
        return &o;
113
    }
114
};
115
#endif
116
117
} /* detail */
118
119
#if defined(BOOST_NO_CXX11_SFINAE_EXPR) || \
120
    defined(BOOST_NO_CXX11_CONSTEXPR) || \
121
    defined(BOOST_NO_CXX11_DECLTYPE)
122
#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
123
124
template<class T>
125
BOOST_FORCEINLINE T*
126
addressof(T& o) BOOST_NOEXCEPT
127
{
128
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x610)) || \
129
    BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)
130
    return boost::detail::addrof<T>::get(o, 0);
131
#else
132
    return boost::detail::addrof<T>::get(boost::detail::addrof_ref<T>(o), 0);
133
#endif
134
}
135
136
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
137
namespace detail {
138
139
template<class T>
140
struct addrof_result {
141
    typedef T* type;
142
};
143
144
} /* detail */
145
146
template<class T, std::size_t N>
147
BOOST_FORCEINLINE typename boost::detail::addrof_result<T[N]>::type
148
addressof(T (&o)[N]) BOOST_NOEXCEPT
149
{
150
    return &o;
151
}
152
#endif
153
154
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
155
template<class T, std::size_t N>
156
BOOST_FORCEINLINE
157
T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N]
158
{
159
   return reinterpret_cast<T(*)[N]>(&o);
160
}
161
162
template<class T, std::size_t N>
163
BOOST_FORCEINLINE
164
const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N]
165
{
166
   return reinterpret_cast<const T(*)[N]>(&o);
167
}
168
#endif
169
#else
170
namespace detail {
171
172
template<class T>
173
T addrof_declval() BOOST_NOEXCEPT;
174
175
template<class>
176
struct addrof_void {
177
    typedef void type;
178
};
179
180
template<class T, class E = void>
181
struct addrof_member_operator {
182
    static constexpr bool value = false;
183
};
184
185
template<class T>
186
struct addrof_member_operator<T, typename
187
    addrof_void<decltype(addrof_declval<T&>().operator&())>::type> {
188
    static constexpr bool value = true;
189
};
190
191
#if BOOST_WORKAROUND(BOOST_INTEL, < 1600)
192
struct addrof_addressable { };
193
194
addrof_addressable*
195
operator&(addrof_addressable&) BOOST_NOEXCEPT;
196
#endif
197
198
template<class T, class E = void>
199
struct addrof_non_member_operator {
200
    static constexpr bool value = false;
201
};
202
203
template<class T>
204
struct addrof_non_member_operator<T, typename
205
    addrof_void<decltype(operator&(addrof_declval<T&>()))>::type> {
206
    static constexpr bool value = true;
207
};
208
209
template<class T, class E = void>
210
struct addrof_expression {
211
    static constexpr bool value = false;
212
};
213
214
template<class T>
215
struct addrof_expression<T,
216
    typename addrof_void<decltype(&addrof_declval<T&>())>::type> {
217
    static constexpr bool value = true;
218
};
219
220
template<class T>
221
struct addrof_is_constexpr {
222
    static constexpr bool value = addrof_expression<T>::value &&
223
        !addrof_member_operator<T>::value &&
224
        !addrof_non_member_operator<T>::value;
225
};
226
227
template<bool E, class T>
228
struct addrof_if { };
229
230
template<class T>
231
struct addrof_if<true, T> {
232
    typedef T* type;
233
};
234
235
template<class T>
236
BOOST_FORCEINLINE
237
typename addrof_if<!addrof_is_constexpr<T>::value, T>::type
238
addressof(T& o) BOOST_NOEXCEPT
239
{
240
    return addrof<T>::get(addrof_ref<T>(o), 0);
241
}
242
243
template<class T>
244
constexpr BOOST_FORCEINLINE
245
typename addrof_if<addrof_is_constexpr<T>::value, T>::type
246
addressof(T& o) BOOST_NOEXCEPT
247
{
248
    return &o;
249
}
250
251
} /* detail */
252
253
template<class T>
254
constexpr BOOST_FORCEINLINE T*
255
addressof(T& o) BOOST_NOEXCEPT
256
{
257
    return boost::detail::addressof(o);
258
}
259
#endif
260
261
} /* boost */
262
#endif
263
264
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
265
    !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
266
namespace boost {
267
268
template<class T>
269
const T* addressof(const T&&) = delete;
270
271
} /* boost */
272
#endif
273
274
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/core/demangle.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED
2
#define BOOST_CORE_DEMANGLE_HPP_INCLUDED
3
4
// core::demangle
5
//
6
// Copyright 2014 Peter Dimov
7
// Copyright 2014 Andrey Semashev
8
//
9
// Distributed under the Boost Software License, Version 1.0.
10
// See accompanying file LICENSE_1_0.txt or copy at
11
// http://www.boost.org/LICENSE_1_0.txt
12
13
#include <boost/config.hpp>
14
#include <string>
15
16
#if defined(BOOST_HAS_PRAGMA_ONCE)
17
# pragma once
18
#endif
19
20
// __has_include is currently supported by GCC and Clang. However GCC 4.9 may have issues and
21
// returns 1 for 'defined( __has_include )', while '__has_include' is actually not supported:
22
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63662
23
#if defined( __has_include ) && (!defined( BOOST_GCC ) || (__GNUC__ + 0) >= 5)
24
# if __has_include(<cxxabi.h>)
25
#  define BOOST_CORE_HAS_CXXABI_H
26
# endif
27
#elif defined( __GLIBCXX__ ) || defined( __GLIBCPP__ )
28
# define BOOST_CORE_HAS_CXXABI_H
29
#endif
30
31
#if defined( BOOST_CORE_HAS_CXXABI_H )
32
# include <cxxabi.h>
33
// For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
34
// (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement
35
// abi::__cxa_demangle(). We detect this implementation by checking the include guard here.
36
# if defined( __GABIXX_CXXABI_H__ )
37
#  undef BOOST_CORE_HAS_CXXABI_H
38
# else
39
#  include <cstdlib>
40
#  include <cstddef>
41
# endif
42
#endif
43
44
namespace boost
45
{
46
47
namespace core
48
{
49
50
inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT;
51
inline void demangle_free( char const * name ) BOOST_NOEXCEPT;
52
53
class scoped_demangled_name
54
{
55
private:
56
    char const * m_p;
57
58
public:
59
    explicit scoped_demangled_name( char const * name ) BOOST_NOEXCEPT :
60
        m_p( demangle_alloc( name ) )
61
0
    {
62
0
    }
63
64
    ~scoped_demangled_name() BOOST_NOEXCEPT
65
0
    {
66
0
        demangle_free( m_p );
67
0
    }
68
69
    char const * get() const BOOST_NOEXCEPT
70
0
    {
71
0
        return m_p;
72
0
    }
73
74
    BOOST_DELETED_FUNCTION(scoped_demangled_name( scoped_demangled_name const& ))
75
    BOOST_DELETED_FUNCTION(scoped_demangled_name& operator= ( scoped_demangled_name const& ))
76
};
77
78
79
#if defined( BOOST_CORE_HAS_CXXABI_H )
80
81
inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT
82
0
{
83
0
    int status = 0;
84
0
    std::size_t size = 0;
85
0
    return abi::__cxa_demangle( name, NULL, &size, &status );
86
0
}
87
88
inline void demangle_free( char const * name ) BOOST_NOEXCEPT
89
0
{
90
0
    std::free( const_cast< char* >( name ) );
91
0
}
92
93
inline std::string demangle( char const * name )
94
0
{
95
0
    scoped_demangled_name demangled_name( name );
96
0
    char const * p = demangled_name.get();
97
0
    if( !p )
98
0
        p = name;
99
0
    return p;
100
0
}
101
102
#else
103
104
inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT
105
{
106
    return name;
107
}
108
109
inline void demangle_free( char const * ) BOOST_NOEXCEPT
110
{
111
}
112
113
inline std::string demangle( char const * name )
114
{
115
    return name;
116
}
117
118
#endif
119
120
} // namespace core
121
122
} // namespace boost
123
124
#undef BOOST_CORE_HAS_CXXABI_H
125
126
#endif // #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/current_function.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
2
#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED
3
4
// MS compatible compilers support #pragma once
5
6
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
7
# pragma once
8
#endif
9
10
//
11
//  boost/current_function.hpp - BOOST_CURRENT_FUNCTION
12
//
13
//  Copyright 2002-2018 Peter Dimov
14
//
15
//  Distributed under the Boost Software License, Version 1.0.
16
//  See accompanying file LICENSE_1_0.txt or copy at
17
//  http://www.boost.org/LICENSE_1_0.txt
18
//
19
//  http://www.boost.org/libs/assert
20
//
21
22
namespace boost
23
{
24
25
namespace detail
26
{
27
28
inline void current_function_helper()
29
0
{
30
0
31
0
#if defined( BOOST_DISABLE_CURRENT_FUNCTION )
32
0
33
0
# define BOOST_CURRENT_FUNCTION "(unknown)"
34
0
35
0
#elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) || defined(__clang__)
36
0
37
0
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
38
0
39
0
#elif defined(__DMC__) && (__DMC__ >= 0x810)
40
0
41
0
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
42
0
43
0
#elif defined(__FUNCSIG__)
44
0
45
0
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
46
0
47
0
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
48
0
49
0
# define BOOST_CURRENT_FUNCTION __FUNCTION__
50
0
51
0
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
52
0
53
0
# define BOOST_CURRENT_FUNCTION __FUNC__
54
0
55
0
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
56
0
57
0
# define BOOST_CURRENT_FUNCTION __func__
58
0
59
0
#elif defined(__cplusplus) && (__cplusplus >= 201103)
60
0
61
0
# define BOOST_CURRENT_FUNCTION __func__
62
0
63
0
#else
64
0
65
0
# define BOOST_CURRENT_FUNCTION "(unknown)"
66
0
67
0
#endif
68
0
69
0
}
70
71
} // namespace detail
72
73
} // namespace boost
74
75
#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/endian/conversion.hpp
Line
Count
Source (jump to first uncovered line)
1
//  boost/endian/conversion.hpp  -------------------------------------------------------//
2
3
//  Copyright Beman Dawes 2010, 2011, 2014
4
5
//  Distributed under the Boost Software License, Version 1.0.
6
//  http://www.boost.org/LICENSE_1_0.txt
7
8
#ifndef BOOST_ENDIAN_CONVERSION_HPP
9
#define BOOST_ENDIAN_CONVERSION_HPP
10
11
#include <boost/endian/detail/endian_reverse.hpp>
12
#include <boost/endian/detail/endian_load.hpp>
13
#include <boost/endian/detail/endian_store.hpp>
14
#include <boost/endian/detail/order.hpp>
15
#include <boost/type_traits/is_class.hpp>
16
#include <boost/type_traits/is_array.hpp>
17
#include <boost/type_traits/integral_constant.hpp>
18
#include <boost/static_assert.hpp>
19
#include <boost/cstdint.hpp>
20
#include <boost/config.hpp>
21
22
//------------------------------------- synopsis ---------------------------------------//
23
24
namespace boost
25
{
26
namespace endian
27
{
28
29
//--------------------------------------------------------------------------------------//
30
//                                                                                      //
31
//                             return-by-value interfaces                               //
32
//                             suggested by Phil Endecott                               //
33
//                                                                                      //
34
//                             user-defined types (UDTs)                                //
35
//                                                                                      //
36
//  All return-by-value conversion function templates are required to be implemented in //
37
//  terms of an unqualified call to "endian_reverse(x)", a function returning the       //
38
//  value of x with endianness reversed. This provides a customization point for any    //
39
//  UDT that provides a "endian_reverse" free-function meeting the requirements.        //
40
//  It must be defined in the same namespace as the UDT itself so that it will be found //
41
//  by argument dependent lookup (ADL).                                                 //
42
//                                                                                      //
43
//--------------------------------------------------------------------------------------//
44
45
  //  reverse byte order
46
  //  requires T to be a non-bool integral type
47
  //  in detail/endian_reverse.hpp
48
  //
49
  //  template<class T> inline BOOST_CONSTEXPR T endian_reverse( T x ) BOOST_NOEXCEPT;
50
51
  //  reverse byte order unless native endianness is big
52
  template <class EndianReversible >
53
    inline BOOST_CONSTEXPR EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT;
54
    //  Returns: x if native endian order is big, otherwise endian_reverse(x)
55
  template <class EndianReversible >
56
    inline BOOST_CONSTEXPR EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT;
57
    //  Returns: x if native endian order is big, otherwise endian_reverse(x)
58
59
  //  reverse byte order unless native endianness is little
60
  template <class EndianReversible >
61
    inline BOOST_CONSTEXPR EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT;
62
    //  Returns: x if native endian order is little, otherwise endian_reverse(x)
63
  template <class EndianReversible >
64
    inline BOOST_CONSTEXPR EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT;
65
    //  Returns: x if native endian order is little, otherwise endian_reverse(x)
66
67
  //  generic conditional reverse byte order
68
  template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
69
    class EndianReversible>
70
      inline BOOST_CONSTEXPR EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT;
71
    //  Returns: If From == To have different values, from.
72
    //           Otherwise endian_reverse(from).
73
    //  Remarks: The From == To test, and as a consequence which form the return takes, is
74
    //           is determined at compile time.
75
76
  //  runtime conditional reverse byte order
77
  template <class EndianReversible >
78
    inline BOOST_CONSTEXPR EndianReversible conditional_reverse(EndianReversible from,
79
      BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
80
        BOOST_NOEXCEPT;
81
      //  Returns: from_order == to_order ? from : endian_reverse(from).
82
83
  //------------------------------------------------------------------------------------//
84
85
86
  //  Q: What happened to bswap, htobe, and the other synonym functions based on names
87
  //     popularized by BSD, OS X, and Linux?
88
  //  A: Turned out these may be implemented as macros on some systems. Ditto POSIX names
89
  //     for such functionality. Since macros would cause endless problems with functions
90
  //     of the same names, and these functions are just synonyms anyhow, they have been
91
  //     removed.
92
93
94
  //------------------------------------------------------------------------------------//
95
  //                                                                                    //
96
  //                            reverse in place interfaces                             //
97
  //                                                                                    //
98
  //                             user-defined types (UDTs)                              //
99
  //                                                                                    //
100
  //  All reverse in place function templates are required to be implemented in terms   //
101
  //  of an unqualified call to "endian_reverse_inplace(x)", a function reversing       //
102
  //  the endianness of x, which is a non-const reference. This provides a              //
103
  //  customization point for any UDT that provides a "reverse_inplace" free-function   //
104
  //  meeting the requirements. The free-function must be declared in the same          //
105
  //  namespace as the UDT itself so that it will be found by argument-dependent        //
106
  //   lookup (ADL).                                                                    //
107
  //                                                                                    //
108
  //------------------------------------------------------------------------------------//
109
110
  //  reverse in place
111
  //  in detail/endian_reverse.hpp
112
  //
113
  //  template <class EndianReversible>
114
  //    inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT;
115
  //
116
  //  Effects: x = endian_reverse(x)
117
118
  //  reverse in place unless native endianness is big
119
  template <class EndianReversibleInplace>
120
    inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
121
    //  Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x)
122
  template <class EndianReversibleInplace>
123
    inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
124
    //  Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x)
125
126
  //  reverse in place unless native endianness is little
127
  template <class EndianReversibleInplace>
128
    inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
129
    //  Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x);
130
  template <class EndianReversibleInplace>
131
    inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
132
    //  Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x);
133
134
  //  generic conditional reverse in place
135
  template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
136
    class EndianReversibleInplace>
137
  inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
138
139
  //  runtime reverse in place
140
  template <class EndianReversibleInplace>
141
  inline void conditional_reverse_inplace(EndianReversibleInplace& x,
142
    BOOST_SCOPED_ENUM(order) from_order,  BOOST_SCOPED_ENUM(order) to_order)
143
    BOOST_NOEXCEPT;
144
145
//----------------------------------- end synopsis -------------------------------------//
146
147
template <class EndianReversible>
148
inline BOOST_CONSTEXPR EndianReversible big_to_native( EndianReversible x ) BOOST_NOEXCEPT
149
{
150
    return boost::endian::conditional_reverse<order::big, order::native>( x );
151
}
152
153
template <class EndianReversible>
154
inline BOOST_CONSTEXPR EndianReversible native_to_big( EndianReversible x ) BOOST_NOEXCEPT
155
{
156
    return boost::endian::conditional_reverse<order::native, order::big>( x );
157
}
158
159
template <class EndianReversible>
160
inline BOOST_CONSTEXPR EndianReversible little_to_native( EndianReversible x ) BOOST_NOEXCEPT
161
27
{
162
27
    return boost::endian::conditional_reverse<order::little, order::native>( x );
163
27
}
_ZN5boost6endian16little_to_nativeItEET_S2_
Line
Count
Source
161
3
{
162
3
    return boost::endian::conditional_reverse<order::little, order::native>( x );
163
3
}
_ZN5boost6endian16little_to_nativeIjEET_S2_
Line
Count
Source
161
6
{
162
6
    return boost::endian::conditional_reverse<order::little, order::native>( x );
163
6
}
_ZN5boost6endian16little_to_nativeIyEET_S2_
Line
Count
Source
161
18
{
162
18
    return boost::endian::conditional_reverse<order::little, order::native>( x );
163
18
}
164
165
template <class EndianReversible>
166
inline BOOST_CONSTEXPR EndianReversible native_to_little( EndianReversible x ) BOOST_NOEXCEPT
167
2
{
168
2
    return boost::endian::conditional_reverse<order::native, order::little>( x );
169
2
}
_ZN5boost6endian16native_to_littleIyEET_S2_
Line
Count
Source
167
1
{
168
1
    return boost::endian::conditional_reverse<order::native, order::little>( x );
169
1
}
_ZN5boost6endian16native_to_littleItEET_S2_
Line
Count
Source
167
1
{
168
1
    return boost::endian::conditional_reverse<order::native, order::little>( x );
169
1
}
170
171
namespace detail
172
{
173
174
template<class EndianReversible>
175
inline BOOST_CONSTEXPR EndianReversible conditional_reverse_impl( EndianReversible x, boost::true_type ) BOOST_NOEXCEPT
176
29
{
177
29
    return x;
178
29
}
_ZN5boost6endian6detail24conditional_reverse_implIyEET_S3_NS_17integral_constantIbLb1EEE
Line
Count
Source
176
19
{
177
19
    return x;
178
19
}
_ZN5boost6endian6detail24conditional_reverse_implItEET_S3_NS_17integral_constantIbLb1EEE
Line
Count
Source
176
4
{
177
4
    return x;
178
4
}
_ZN5boost6endian6detail24conditional_reverse_implIjEET_S3_NS_17integral_constantIbLb1EEE
Line
Count
Source
176
6
{
177
6
    return x;
178
6
}
179
180
template<class EndianReversible>
181
inline BOOST_CONSTEXPR EndianReversible conditional_reverse_impl( EndianReversible x, boost::false_type ) BOOST_NOEXCEPT
182
{
183
    return endian_reverse( x );
184
}
185
186
} // namespace detail
187
188
// generic conditional reverse
189
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class EndianReversible>
190
inline BOOST_CONSTEXPR EndianReversible conditional_reverse( EndianReversible x ) BOOST_NOEXCEPT
191
29
{
192
29
    BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
193
29
    return detail::conditional_reverse_impl( x, boost::integral_constant<bool, From == To>() );
194
29
}
_ZN5boost6endian19conditional_reverseILNS0_5orderE1ELS2_1EyEET1_S3_
Line
Count
Source
191
19
{
192
19
    BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
193
19
    return detail::conditional_reverse_impl( x, boost::integral_constant<bool, From == To>() );
194
19
}
_ZN5boost6endian19conditional_reverseILNS0_5orderE1ELS2_1EtEET1_S3_
Line
Count
Source
191
4
{
192
4
    BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
193
4
    return detail::conditional_reverse_impl( x, boost::integral_constant<bool, From == To>() );
194
4
}
_ZN5boost6endian19conditional_reverseILNS0_5orderE1ELS2_1EjEET1_S3_
Line
Count
Source
191
6
{
192
6
    BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
193
6
    return detail::conditional_reverse_impl( x, boost::integral_constant<bool, From == To>() );
194
6
}
195
196
// runtime conditional reverse
197
template <class EndianReversible>
198
inline BOOST_CONSTEXPR EndianReversible conditional_reverse( EndianReversible x,
199
    BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order ) BOOST_NOEXCEPT
200
{
201
    BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
202
    return from_order == to_order? x: endian_reverse( x );
203
}
204
205
//--------------------------------------------------------------------------------------//
206
//                           reverse-in-place implementation                            //
207
//--------------------------------------------------------------------------------------//
208
209
template <class EndianReversibleInplace>
210
inline void big_to_native_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
211
{
212
    boost::endian::conditional_reverse_inplace<order::big, order::native>( x );
213
}
214
215
template <class EndianReversibleInplace>
216
inline void native_to_big_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
217
{
218
    boost::endian::conditional_reverse_inplace<order::native, order::big>( x );
219
}
220
221
template <class EndianReversibleInplace>
222
inline void little_to_native_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
223
{
224
    boost::endian::conditional_reverse_inplace<order::little, order::native>( x );
225
}
226
227
template <class EndianReversibleInplace>
228
inline void native_to_little_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
229
{
230
    boost::endian::conditional_reverse_inplace<order::native, order::little>( x );
231
}
232
233
namespace detail
234
{
235
236
template<class EndianReversibleInplace>
237
inline void conditional_reverse_inplace_impl( EndianReversibleInplace&, boost::true_type ) BOOST_NOEXCEPT
238
{
239
}
240
241
template<class EndianReversibleInplace>
242
inline void conditional_reverse_inplace_impl( EndianReversibleInplace& x, boost::false_type ) BOOST_NOEXCEPT
243
{
244
    endian_reverse_inplace( x );
245
}
246
247
}  // namespace detail
248
249
// generic conditional reverse in place
250
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class EndianReversibleInplace>
251
inline void conditional_reverse_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
252
{
253
    BOOST_STATIC_ASSERT(
254
        boost::is_class<EndianReversibleInplace>::value ||
255
        boost::is_array<EndianReversibleInplace>::value ||
256
        detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
257
258
    detail::conditional_reverse_inplace_impl( x, boost::integral_constant<bool, From == To>() );
259
}
260
261
// runtime reverse in place
262
template <class EndianReversibleInplace>
263
inline void conditional_reverse_inplace( EndianReversibleInplace& x,
264
    BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order ) BOOST_NOEXCEPT
265
{
266
    BOOST_STATIC_ASSERT(
267
        boost::is_class<EndianReversibleInplace>::value ||
268
        boost::is_array<EndianReversibleInplace>::value ||
269
        detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
270
271
    if( from_order != to_order )
272
    {
273
        endian_reverse_inplace( x );
274
    }
275
}
276
277
// load/store convenience functions
278
279
// load 16
280
281
inline boost::int16_t load_little_s16( unsigned char const * p ) BOOST_NOEXCEPT
282
0
{
283
0
    return boost::endian::endian_load<boost::int16_t, 2, order::little>( p );
284
0
}
285
286
inline boost::uint16_t load_little_u16( unsigned char const * p ) BOOST_NOEXCEPT
287
0
{
288
0
    return boost::endian::endian_load<boost::uint16_t, 2, order::little>( p );
289
0
}
290
291
inline boost::int16_t load_big_s16( unsigned char const * p ) BOOST_NOEXCEPT
292
0
{
293
0
    return boost::endian::endian_load<boost::int16_t, 2, order::big>( p );
294
0
}
295
296
inline boost::uint16_t load_big_u16( unsigned char const * p ) BOOST_NOEXCEPT
297
0
{
298
0
    return boost::endian::endian_load<boost::uint16_t, 2, order::big>( p );
299
0
}
300
301
// load 24
302
303
inline boost::int32_t load_little_s24( unsigned char const * p ) BOOST_NOEXCEPT
304
0
{
305
0
    return boost::endian::endian_load<boost::int32_t, 3, order::little>( p );
306
0
}
307
308
inline boost::uint32_t load_little_u24( unsigned char const * p ) BOOST_NOEXCEPT
309
0
{
310
0
    return boost::endian::endian_load<boost::uint32_t, 3, order::little>( p );
311
0
}
312
313
inline boost::int32_t load_big_s24( unsigned char const * p ) BOOST_NOEXCEPT
314
0
{
315
0
    return boost::endian::endian_load<boost::int32_t, 3, order::big>( p );
316
0
}
317
318
inline boost::uint32_t load_big_u24( unsigned char const * p ) BOOST_NOEXCEPT
319
0
{
320
0
    return boost::endian::endian_load<boost::uint32_t, 3, order::big>( p );
321
0
}
322
323
// load 32
324
325
inline boost::int32_t load_little_s32( unsigned char const * p ) BOOST_NOEXCEPT
326
0
{
327
0
    return boost::endian::endian_load<boost::int32_t, 4, order::little>( p );
328
0
}
329
330
inline boost::uint32_t load_little_u32( unsigned char const * p ) BOOST_NOEXCEPT
331
0
{
332
0
    return boost::endian::endian_load<boost::uint32_t, 4, order::little>( p );
333
0
}
334
335
inline boost::int32_t load_big_s32( unsigned char const * p ) BOOST_NOEXCEPT
336
0
{
337
0
    return boost::endian::endian_load<boost::int32_t, 4, order::big>( p );
338
0
}
339
340
inline boost::uint32_t load_big_u32( unsigned char const * p ) BOOST_NOEXCEPT
341
0
{
342
0
    return boost::endian::endian_load<boost::uint32_t, 4, order::big>( p );
343
0
}
344
345
// load 40
346
347
inline boost::int64_t load_little_s40( unsigned char const * p ) BOOST_NOEXCEPT
348
0
{
349
0
    return boost::endian::endian_load<boost::int64_t, 5, order::little>( p );
350
0
}
351
352
inline boost::uint64_t load_little_u40( unsigned char const * p ) BOOST_NOEXCEPT
353
0
{
354
0
    return boost::endian::endian_load<boost::uint64_t, 5, order::little>( p );
355
0
}
356
357
inline boost::int64_t load_big_s40( unsigned char const * p ) BOOST_NOEXCEPT
358
0
{
359
0
    return boost::endian::endian_load<boost::int64_t, 5, order::big>( p );
360
0
}
361
362
inline boost::uint64_t load_big_u40( unsigned char const * p ) BOOST_NOEXCEPT
363
0
{
364
0
    return boost::endian::endian_load<boost::uint64_t, 5, order::big>( p );
365
0
}
366
367
// load 48
368
369
inline boost::int64_t load_little_s48( unsigned char const * p ) BOOST_NOEXCEPT
370
0
{
371
0
    return boost::endian::endian_load<boost::int64_t, 6, order::little>( p );
372
0
}
373
374
inline boost::uint64_t load_little_u48( unsigned char const * p ) BOOST_NOEXCEPT
375
0
{
376
0
    return boost::endian::endian_load<boost::uint64_t, 6, order::little>( p );
377
0
}
378
379
inline boost::int64_t load_big_s48( unsigned char const * p ) BOOST_NOEXCEPT
380
0
{
381
0
    return boost::endian::endian_load<boost::int64_t, 6, order::big>( p );
382
0
}
383
384
inline boost::uint64_t load_big_u48( unsigned char const * p ) BOOST_NOEXCEPT
385
0
{
386
0
    return boost::endian::endian_load<boost::uint64_t, 6, order::big>( p );
387
0
}
388
389
// load 56
390
391
inline boost::int64_t load_little_s56( unsigned char const * p ) BOOST_NOEXCEPT
392
0
{
393
0
    return boost::endian::endian_load<boost::int64_t, 7, order::little>( p );
394
0
}
395
396
inline boost::uint64_t load_little_u56( unsigned char const * p ) BOOST_NOEXCEPT
397
0
{
398
0
    return boost::endian::endian_load<boost::uint64_t, 7, order::little>( p );
399
0
}
400
401
inline boost::int64_t load_big_s56( unsigned char const * p ) BOOST_NOEXCEPT
402
0
{
403
0
    return boost::endian::endian_load<boost::int64_t, 7, order::big>( p );
404
0
}
405
406
inline boost::uint64_t load_big_u56( unsigned char const * p ) BOOST_NOEXCEPT
407
0
{
408
0
    return boost::endian::endian_load<boost::uint64_t, 7, order::big>( p );
409
0
}
410
411
// load 64
412
413
inline boost::int64_t load_little_s64( unsigned char const * p ) BOOST_NOEXCEPT
414
0
{
415
0
    return boost::endian::endian_load<boost::int64_t, 8, order::little>( p );
416
0
}
417
418
inline boost::uint64_t load_little_u64( unsigned char const * p ) BOOST_NOEXCEPT
419
0
{
420
0
    return boost::endian::endian_load<boost::uint64_t, 8, order::little>( p );
421
0
}
422
423
inline boost::int64_t load_big_s64( unsigned char const * p ) BOOST_NOEXCEPT
424
0
{
425
0
    return boost::endian::endian_load<boost::int64_t, 8, order::big>( p );
426
0
}
427
428
inline boost::uint64_t load_big_u64( unsigned char const * p ) BOOST_NOEXCEPT
429
0
{
430
0
    return boost::endian::endian_load<boost::uint64_t, 8, order::big>( p );
431
0
}
432
433
// store 16
434
435
inline void store_little_s16( unsigned char * p, boost::int16_t v )
436
0
{
437
0
    boost::endian::endian_store<boost::int16_t, 2, order::little>( p, v );
438
0
}
439
440
inline void store_little_u16( unsigned char * p, boost::uint16_t v )
441
0
{
442
0
    boost::endian::endian_store<boost::uint16_t, 2, order::little>( p, v );
443
0
}
444
445
inline void store_big_s16( unsigned char * p, boost::int16_t v )
446
0
{
447
0
    boost::endian::endian_store<boost::int16_t, 2, order::big>( p, v );
448
0
}
449
450
inline void store_big_u16( unsigned char * p, boost::uint16_t v )
451
0
{
452
0
    boost::endian::endian_store<boost::uint16_t, 2, order::big>( p, v );
453
0
}
454
455
// store 24
456
457
inline void store_little_s24( unsigned char * p, boost::int32_t v )
458
0
{
459
0
    boost::endian::endian_store<boost::int32_t, 3, order::little>( p, v );
460
0
}
461
462
inline void store_little_u24( unsigned char * p, boost::uint32_t v )
463
0
{
464
0
    boost::endian::endian_store<boost::uint32_t, 3, order::little>( p, v );
465
0
}
466
467
inline void store_big_s24( unsigned char * p, boost::int32_t v )
468
0
{
469
0
    boost::endian::endian_store<boost::int32_t, 3, order::big>( p, v );
470
0
}
471
472
inline void store_big_u24( unsigned char * p, boost::uint32_t v )
473
0
{
474
0
    boost::endian::endian_store<boost::uint32_t, 3, order::big>( p, v );
475
0
}
476
477
// store 32
478
479
inline void store_little_s32( unsigned char * p, boost::int32_t v )
480
0
{
481
0
    boost::endian::endian_store<boost::int32_t, 4, order::little>( p, v );
482
0
}
483
484
inline void store_little_u32( unsigned char * p, boost::uint32_t v )
485
0
{
486
0
    boost::endian::endian_store<boost::uint32_t, 4, order::little>( p, v );
487
0
}
488
489
inline void store_big_s32( unsigned char * p, boost::int32_t v )
490
0
{
491
0
    boost::endian::endian_store<boost::int32_t, 4, order::big>( p, v );
492
0
}
493
494
inline void store_big_u32( unsigned char * p, boost::uint32_t v )
495
0
{
496
0
    boost::endian::endian_store<boost::uint32_t, 4, order::big>( p, v );
497
0
}
498
499
// store 40
500
501
inline void store_little_s40( unsigned char * p, boost::int64_t v )
502
0
{
503
0
    boost::endian::endian_store<boost::int64_t, 5, order::little>( p, v );
504
0
}
505
506
inline void store_little_u40( unsigned char * p, boost::uint64_t v )
507
0
{
508
0
    boost::endian::endian_store<boost::uint64_t, 5, order::little>( p, v );
509
0
}
510
511
inline void store_big_s40( unsigned char * p, boost::int64_t v )
512
0
{
513
0
    boost::endian::endian_store<boost::int64_t, 5, order::big>( p, v );
514
0
}
515
516
inline void store_big_u40( unsigned char * p, boost::uint64_t v )
517
0
{
518
0
    boost::endian::endian_store<boost::uint64_t, 5, order::big>( p, v );
519
0
}
520
521
// store 48
522
523
inline void store_little_s48( unsigned char * p, boost::int64_t v )
524
0
{
525
0
    boost::endian::endian_store<boost::int64_t, 6, order::little>( p, v );
526
0
}
527
528
inline void store_little_u48( unsigned char * p, boost::uint64_t v )
529
0
{
530
0
    boost::endian::endian_store<boost::uint64_t, 6, order::little>( p, v );
531
0
}
532
533
inline void store_big_s48( unsigned char * p, boost::int64_t v )
534
0
{
535
0
    boost::endian::endian_store<boost::int64_t, 6, order::big>( p, v );
536
0
}
537
538
inline void store_big_u48( unsigned char * p, boost::uint64_t v )
539
0
{
540
0
    boost::endian::endian_store<boost::uint64_t, 6, order::big>( p, v );
541
0
}
542
543
// store 56
544
545
inline void store_little_s56( unsigned char * p, boost::int64_t v )
546
0
{
547
0
    boost::endian::endian_store<boost::int64_t, 7, order::little>( p, v );
548
0
}
549
550
inline void store_little_u56( unsigned char * p, boost::uint64_t v )
551
0
{
552
0
    boost::endian::endian_store<boost::uint64_t, 7, order::little>( p, v );
553
0
}
554
555
inline void store_big_s56( unsigned char * p, boost::int64_t v )
556
0
{
557
0
    boost::endian::endian_store<boost::int64_t, 7, order::big>( p, v );
558
0
}
559
560
inline void store_big_u56( unsigned char * p, boost::uint64_t v )
561
0
{
562
0
    boost::endian::endian_store<boost::uint64_t, 7, order::big>( p, v );
563
0
}
564
565
// store 64
566
567
inline void store_little_s64( unsigned char * p, boost::int64_t v )
568
0
{
569
0
    boost::endian::endian_store<boost::int64_t, 8, order::little>( p, v );
570
0
}
571
572
inline void store_little_u64( unsigned char * p, boost::uint64_t v )
573
0
{
574
0
    boost::endian::endian_store<boost::uint64_t, 8, order::little>( p, v );
575
0
}
576
577
inline void store_big_s64( unsigned char * p, boost::int64_t v )
578
0
{
579
0
    boost::endian::endian_store<boost::int64_t, 8, order::big>( p, v );
580
0
}
581
582
inline void store_big_u64( unsigned char * p, boost::uint64_t v )
583
0
{
584
0
    boost::endian::endian_store<boost::uint64_t, 8, order::big>( p, v );
585
0
}
586
587
}  // namespace endian
588
}  // namespace boost
589
590
#endif // BOOST_ENDIAN_CONVERSION_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/endian/detail/endian_load.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef BOOST_ENDIAN_DETAIL_ENDIAN_LOAD_HPP_INCLUDED
2
#define BOOST_ENDIAN_DETAIL_ENDIAN_LOAD_HPP_INCLUDED
3
4
// Copyright 2019 Peter Dimov
5
//
6
// Distributed under the Boost Software License, Version 1.0.
7
// http://www.boost.org/LICENSE_1_0.txt
8
9
#include <boost/endian/detail/endian_reverse.hpp>
10
#include <boost/endian/detail/order.hpp>
11
#include <boost/endian/detail/integral_by_size.hpp>
12
#include <boost/endian/detail/is_trivially_copyable.hpp>
13
#include <boost/type_traits/is_signed.hpp>
14
#include <boost/type_traits/is_integral.hpp>
15
#include <boost/type_traits/is_enum.hpp>
16
#include <boost/static_assert.hpp>
17
#include <cstddef>
18
#include <cstring>
19
20
namespace boost
21
{
22
namespace endian
23
{
24
25
namespace detail
26
{
27
28
template<class T, std::size_t N1, BOOST_SCOPED_ENUM(order) O1, std::size_t N2, BOOST_SCOPED_ENUM(order) O2> struct endian_load_impl
29
{
30
};
31
32
} // namespace detail
33
34
// Requires:
35
//
36
//    sizeof(T) must be 1, 2, 4, or 8
37
//    1 <= N <= sizeof(T)
38
//    T is TriviallyCopyable
39
//    if N < sizeof(T), T is integral or enum
40
41
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) Order>
42
inline T endian_load( unsigned char const * p ) BOOST_NOEXCEPT
43
0
{
44
0
    BOOST_STATIC_ASSERT( sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8 );
45
0
    BOOST_STATIC_ASSERT( N >= 1 && N <= sizeof(T) );
46
0
47
0
    return detail::endian_load_impl<T, sizeof(T), order::native, N, Order>()( p );
48
0
}
Unexecuted instantiation: _ZN5boost6endian11endian_loadIsLm2ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadItLm2ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIsLm2ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadItLm2ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIiLm3ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIjLm3ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIiLm3ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIjLm3ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIiLm4ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIjLm4ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIiLm4ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIjLm4ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIxLm5ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIyLm5ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIxLm5ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIyLm5ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIxLm6ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIyLm6ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIxLm6ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIyLm6ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIxLm7ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIyLm7ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIxLm7ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIyLm7ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIxLm8ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIyLm8ELNS0_5orderE1EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIxLm8ELNS0_5orderE0EEET_PKh
Unexecuted instantiation: _ZN5boost6endian11endian_loadIyLm8ELNS0_5orderE0EEET_PKh
49
50
namespace detail
51
{
52
53
// same endianness, same size
54
55
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O> struct endian_load_impl<T, N, O, N, O>
56
{
57
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
58
0
    {
59
0
        BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
60
0
61
0
        T t;
62
0
        std::memcpy( &t, p, N );
63
0
        return t;
64
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIsLm2ELNS0_5orderE1ELm2ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implItLm2ELNS0_5orderE1ELm2ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIiLm4ELNS0_5orderE1ELm4ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIjLm4ELNS0_5orderE1ELm4ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIxLm8ELNS0_5orderE1ELm8ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIyLm8ELNS0_5orderE1ELm8ELS3_1EEclEPKh
65
};
66
67
// same size, reverse endianness
68
69
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O1, BOOST_SCOPED_ENUM(order) O2> struct endian_load_impl<T, N, O1, N, O2>
70
{
71
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
72
0
    {
73
0
        BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
74
0
75
0
        typename integral_by_size<N>::type tmp;
76
0
        std::memcpy( &tmp, p, N );
77
0
78
0
        endian_reverse_inplace( tmp );
79
0
80
0
        T t;
81
0
        std::memcpy( &t, &tmp, N );
82
0
        return t;
83
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIsLm2ELNS0_5orderE1ELm2ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implItLm2ELNS0_5orderE1ELm2ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIiLm4ELNS0_5orderE1ELm4ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIjLm4ELNS0_5orderE1ELm4ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIxLm8ELNS0_5orderE1ELm8ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIyLm8ELNS0_5orderE1ELm8ELS3_0EEclEPKh
84
};
85
86
// expanding load 1 -> 2
87
88
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 2, Order, 1, order::little>
89
{
90
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
91
    {
92
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
93
94
        unsigned char tmp[ 2 ];
95
96
        tmp[0] = p[0];
97
        tmp[1] = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
98
99
        return boost::endian::endian_load<T, 2, order::little>( tmp );
100
    }
101
};
102
103
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 2, Order, 1, order::big>
104
{
105
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
106
    {
107
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
108
109
        unsigned char tmp[ 2 ];
110
111
        tmp[0] = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
112
        tmp[1] = p[0];
113
114
        return boost::endian::endian_load<T, 2, order::big>( tmp );
115
    }
116
};
117
118
// expanding load 1 -> 4
119
120
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 1, order::little>
121
{
122
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
123
    {
124
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
125
126
        unsigned char tmp[ 4 ];
127
128
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
129
130
        tmp[0] = p[0];
131
        tmp[1] = fill;
132
        tmp[2] = fill;
133
        tmp[3] = fill;
134
135
        return boost::endian::endian_load<T, 4, order::little>( tmp );
136
    }
137
};
138
139
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 1, order::big>
140
{
141
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
142
    {
143
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
144
145
        unsigned char tmp[ 4 ];
146
147
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
148
149
        tmp[0] = fill;
150
        tmp[1] = fill;
151
        tmp[2] = fill;
152
        tmp[3] = p[0];
153
154
        return boost::endian::endian_load<T, 4, order::big>( tmp );
155
    }
156
};
157
158
// expanding load 2 -> 4
159
160
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 2, order::little>
161
{
162
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
163
    {
164
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
165
166
        unsigned char tmp[ 4 ];
167
168
        unsigned char fill = boost::is_signed<T>::value && ( p[1] & 0x80 )? 0xFF: 0x00;
169
170
        tmp[0] = p[0];
171
        tmp[1] = p[1];
172
        tmp[2] = fill;
173
        tmp[3] = fill;
174
175
        return boost::endian::endian_load<T, 4, order::little>( tmp );
176
    }
177
};
178
179
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 2, order::big>
180
{
181
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
182
    {
183
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
184
185
        unsigned char tmp[ 4 ];
186
187
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
188
189
        tmp[0] = fill;
190
        tmp[1] = fill;
191
        tmp[2] = p[0];
192
        tmp[3] = p[1];
193
194
        return boost::endian::endian_load<T, 4, order::big>( tmp );
195
    }
196
};
197
198
// expanding load 3 -> 4
199
200
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 3, order::little>
201
{
202
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
203
0
    {
204
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
205
0
206
0
        unsigned char tmp[ 4 ];
207
0
208
0
        tmp[0] = p[0];
209
0
        tmp[1] = p[1];
210
0
        tmp[2] = p[2];
211
0
        tmp[3] = boost::is_signed<T>::value && ( p[2] & 0x80 )? 0xFF: 0x00;
212
0
213
0
        return boost::endian::endian_load<T, 4, order::little>( tmp );
214
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIiLm4ELNS0_5orderE1ELm3ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIjLm4ELNS0_5orderE1ELm3ELS3_1EEclEPKh
215
};
216
217
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 3, order::big>
218
{
219
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
220
0
    {
221
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
222
0
223
0
        unsigned char tmp[ 4 ];
224
0
225
0
        tmp[0] = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
226
0
        tmp[1] = p[0];
227
0
        tmp[2] = p[1];
228
0
        tmp[3] = p[2];
229
0
230
0
        return boost::endian::endian_load<T, 4, order::big>( tmp );
231
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIiLm4ELNS0_5orderE1ELm3ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIjLm4ELNS0_5orderE1ELm3ELS3_0EEclEPKh
232
};
233
234
// expanding load 1 -> 8
235
236
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 1, order::little>
237
{
238
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
239
    {
240
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
241
242
        unsigned char tmp[ 8 ];
243
244
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
245
246
        tmp[0] = p[0];
247
248
        tmp[1] = fill;
249
        tmp[2] = fill;
250
        tmp[3] = fill;
251
        tmp[4] = fill;
252
        tmp[5] = fill;
253
        tmp[6] = fill;
254
        tmp[7] = fill;
255
256
        return boost::endian::endian_load<T, 8, order::little>( tmp );
257
    }
258
};
259
260
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 1, order::big>
261
{
262
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
263
    {
264
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
265
266
        unsigned char tmp[ 8 ];
267
268
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
269
270
        tmp[0] = fill;
271
        tmp[1] = fill;
272
        tmp[2] = fill;
273
        tmp[3] = fill;
274
        tmp[4] = fill;
275
        tmp[5] = fill;
276
        tmp[6] = fill;
277
278
        tmp[7] = p[0];
279
280
        return boost::endian::endian_load<T, 8, order::big>( tmp );
281
    }
282
};
283
284
// expanding load 2 -> 8
285
286
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 2, order::little>
287
{
288
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
289
    {
290
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
291
292
        unsigned char tmp[ 8 ];
293
294
        unsigned char fill = boost::is_signed<T>::value && ( p[1] & 0x80 )? 0xFF: 0x00;
295
296
        tmp[0] = p[0];
297
        tmp[1] = p[1];
298
299
        tmp[2] = fill;
300
        tmp[3] = fill;
301
        tmp[4] = fill;
302
        tmp[5] = fill;
303
        tmp[6] = fill;
304
        tmp[7] = fill;
305
306
        return boost::endian::endian_load<T, 8, order::little>( tmp );
307
    }
308
};
309
310
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 2, order::big>
311
{
312
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
313
    {
314
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
315
316
        unsigned char tmp[ 8 ];
317
318
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
319
320
        tmp[0] = fill;
321
        tmp[1] = fill;
322
        tmp[2] = fill;
323
        tmp[3] = fill;
324
        tmp[4] = fill;
325
        tmp[5] = fill;
326
327
        tmp[6] = p[0];
328
        tmp[7] = p[1];
329
330
        return boost::endian::endian_load<T, 8, order::big>( tmp );
331
    }
332
};
333
334
// expanding load 3 -> 8
335
336
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 3, order::little>
337
{
338
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
339
    {
340
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
341
342
        unsigned char tmp[ 8 ];
343
344
        unsigned char fill = boost::is_signed<T>::value && ( p[2] & 0x80 )? 0xFF: 0x00;
345
346
        tmp[0] = p[0];
347
        tmp[1] = p[1];
348
        tmp[2] = p[2];
349
350
        tmp[3] = fill;
351
        tmp[4] = fill;
352
        tmp[5] = fill;
353
        tmp[6] = fill;
354
        tmp[7] = fill;
355
356
        return boost::endian::endian_load<T, 8, order::little>( tmp );
357
    }
358
};
359
360
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 3, order::big>
361
{
362
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
363
    {
364
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
365
366
        unsigned char tmp[ 8 ];
367
368
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
369
370
        tmp[0] = fill;
371
        tmp[1] = fill;
372
        tmp[2] = fill;
373
        tmp[3] = fill;
374
        tmp[4] = fill;
375
376
        tmp[5] = p[0];
377
        tmp[6] = p[1];
378
        tmp[7] = p[2];
379
380
        return boost::endian::endian_load<T, 8, order::big>( tmp );
381
    }
382
};
383
384
// expanding load 4 -> 8
385
386
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 4, order::little>
387
{
388
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
389
    {
390
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
391
392
        unsigned char tmp[ 8 ];
393
394
        unsigned char fill = boost::is_signed<T>::value && ( p[3] & 0x80 )? 0xFF: 0x00;
395
396
        tmp[0] = p[0];
397
        tmp[1] = p[1];
398
        tmp[2] = p[2];
399
        tmp[3] = p[3];
400
401
        tmp[4] = fill;
402
        tmp[5] = fill;
403
        tmp[6] = fill;
404
        tmp[7] = fill;
405
406
        return boost::endian::endian_load<T, 8, order::little>( tmp );
407
    }
408
};
409
410
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 4, order::big>
411
{
412
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
413
    {
414
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
415
416
        unsigned char tmp[ 8 ];
417
418
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
419
420
        tmp[0] = fill;
421
        tmp[1] = fill;
422
        tmp[2] = fill;
423
        tmp[3] = fill;
424
425
        tmp[4] = p[0];
426
        tmp[5] = p[1];
427
        tmp[6] = p[2];
428
        tmp[7] = p[3];
429
430
        return boost::endian::endian_load<T, 8, order::big>( tmp );
431
    }
432
};
433
434
// expanding load 5 -> 8
435
436
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 5, order::little>
437
{
438
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
439
0
    {
440
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
441
0
442
0
        unsigned char tmp[ 8 ];
443
0
444
0
        unsigned char fill = boost::is_signed<T>::value && ( p[4] & 0x80 )? 0xFF: 0x00;
445
0
446
0
        tmp[0] = p[0];
447
0
        tmp[1] = p[1];
448
0
        tmp[2] = p[2];
449
0
        tmp[3] = p[3];
450
0
        tmp[4] = p[4];
451
0
452
0
        tmp[5] = fill;
453
0
        tmp[6] = fill;
454
0
        tmp[7] = fill;
455
0
456
0
        return boost::endian::endian_load<T, 8, order::little>( tmp );
457
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIxLm8ELNS0_5orderE1ELm5ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIyLm8ELNS0_5orderE1ELm5ELS3_1EEclEPKh
458
};
459
460
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 5, order::big>
461
{
462
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
463
0
    {
464
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
465
0
466
0
        unsigned char tmp[ 8 ];
467
0
468
0
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
469
0
470
0
        tmp[0] = fill;
471
0
        tmp[1] = fill;
472
0
        tmp[2] = fill;
473
0
474
0
        tmp[3] = p[0];
475
0
        tmp[4] = p[1];
476
0
        tmp[5] = p[2];
477
0
        tmp[6] = p[3];
478
0
        tmp[7] = p[4];
479
0
480
0
        return boost::endian::endian_load<T, 8, order::big>( tmp );
481
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIxLm8ELNS0_5orderE1ELm5ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIyLm8ELNS0_5orderE1ELm5ELS3_0EEclEPKh
482
};
483
484
// expanding load 6 -> 8
485
486
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 6, order::little>
487
{
488
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
489
0
    {
490
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
491
0
492
0
        unsigned char tmp[ 8 ];
493
0
494
0
        unsigned char fill = boost::is_signed<T>::value && ( p[5] & 0x80 )? 0xFF: 0x00;
495
0
496
0
        tmp[0] = p[0];
497
0
        tmp[1] = p[1];
498
0
        tmp[2] = p[2];
499
0
        tmp[3] = p[3];
500
0
        tmp[4] = p[4];
501
0
        tmp[5] = p[5];
502
0
503
0
        tmp[6] = fill;
504
0
        tmp[7] = fill;
505
0
506
0
        return boost::endian::endian_load<T, 8, order::little>( tmp );
507
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIxLm8ELNS0_5orderE1ELm6ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIyLm8ELNS0_5orderE1ELm6ELS3_1EEclEPKh
508
};
509
510
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 6, order::big>
511
{
512
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
513
0
    {
514
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
515
0
516
0
        unsigned char tmp[ 8 ];
517
0
518
0
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
519
0
520
0
        tmp[0] = fill;
521
0
        tmp[1] = fill;
522
0
523
0
        tmp[2] = p[0];
524
0
        tmp[3] = p[1];
525
0
        tmp[4] = p[2];
526
0
        tmp[5] = p[3];
527
0
        tmp[6] = p[4];
528
0
        tmp[7] = p[5];
529
0
530
0
        return boost::endian::endian_load<T, 8, order::big>( tmp );
531
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIxLm8ELNS0_5orderE1ELm6ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIyLm8ELNS0_5orderE1ELm6ELS3_0EEclEPKh
532
};
533
534
// expanding load 7 -> 8
535
536
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 7, order::little>
537
{
538
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
539
0
    {
540
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
541
0
542
0
        unsigned char tmp[ 8 ];
543
0
544
0
        unsigned char fill = boost::is_signed<T>::value && ( p[6] & 0x80 )? 0xFF: 0x00;
545
0
546
0
        tmp[0] = p[0];
547
0
        tmp[1] = p[1];
548
0
        tmp[2] = p[2];
549
0
        tmp[3] = p[3];
550
0
        tmp[4] = p[4];
551
0
        tmp[5] = p[5];
552
0
        tmp[6] = p[6];
553
0
554
0
        tmp[7] = fill;
555
0
556
0
        return boost::endian::endian_load<T, 8, order::little>( tmp );
557
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIxLm8ELNS0_5orderE1ELm7ELS3_1EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIyLm8ELNS0_5orderE1ELm7ELS3_1EEclEPKh
558
};
559
560
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 7, order::big>
561
{
562
    inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
563
0
    {
564
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
565
0
566
0
        unsigned char tmp[ 8 ];
567
0
568
0
        unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
569
0
570
0
        tmp[0] = fill;
571
0
572
0
        tmp[1] = p[0];
573
0
        tmp[2] = p[1];
574
0
        tmp[3] = p[2];
575
0
        tmp[4] = p[3];
576
0
        tmp[5] = p[4];
577
0
        tmp[6] = p[5];
578
0
        tmp[7] = p[6];
579
0
580
0
        return boost::endian::endian_load<T, 8, order::big>( tmp );
581
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIxLm8ELNS0_5orderE1ELm7ELS3_0EEclEPKh
Unexecuted instantiation: _ZNK5boost6endian6detail16endian_load_implIyLm8ELNS0_5orderE1ELm7ELS3_0EEclEPKh
582
};
583
584
} // namespace detail
585
586
} // namespace endian
587
} // namespace boost
588
589
#endif  // BOOST_ENDIAN_DETAIL_ENDIAN_LOAD_HPP_INCLUDED
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/endian/detail/endian_reverse.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED
2
#define BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED
3
4
// Copyright 2019, 2020 Peter Dimov
5
// Distributed under the Boost Software License, Version 1.0.
6
// https://www.boost.org/LICENSE_1_0.txt
7
8
#include <boost/endian/detail/integral_by_size.hpp>
9
#include <boost/endian/detail/intrinsic.hpp>
10
#include <boost/endian/detail/is_scoped_enum.hpp>
11
#include <boost/type_traits/is_integral.hpp>
12
#include <boost/type_traits/is_same.hpp>
13
#include <boost/type_traits/enable_if.hpp>
14
#include <boost/type_traits/is_class.hpp>
15
#include <boost/type_traits/integral_constant.hpp>
16
#include <boost/static_assert.hpp>
17
#include <boost/cstdint.hpp>
18
#include <boost/config.hpp>
19
#include <cstddef>
20
#include <cstring>
21
22
#if defined(BOOST_ENDIAN_NO_INTRINSICS)
23
# if defined(BOOST_NO_CXX14_CONSTEXPR)
24
#  define BOOST_ENDIAN_CONSTEXPR
25
# else
26
#  define BOOST_ENDIAN_CONSTEXPR constexpr
27
# endif
28
#else
29
# if defined(BOOST_ENDIAN_CONSTEXPR_INTRINSICS)
30
#  define BOOST_ENDIAN_CONSTEXPR BOOST_CONSTEXPR
31
# else
32
#  define BOOST_ENDIAN_CONSTEXPR
33
# endif
34
#endif
35
36
namespace boost
37
{
38
namespace endian
39
{
40
41
namespace detail
42
{
43
44
//  -- portable approach suggested by tymofey, with avoidance of undefined behavior
45
//     as suggested by Giovanni Piero Deretta, with a further refinement suggested
46
//     by Pyry Jahkola.
47
//  -- intrinsic approach suggested by reviewers, and by David Stone, who provided
48
//     his Boost licensed macro implementation (detail/intrinsic.hpp)
49
50
inline uint8_t BOOST_CONSTEXPR endian_reverse_impl( uint8_t x ) BOOST_NOEXCEPT
51
0
{
52
0
    return x;
53
0
}
54
55
inline uint16_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint16_t x ) BOOST_NOEXCEPT
56
0
{
57
0
#ifdef BOOST_ENDIAN_NO_INTRINSICS
58
0
59
0
    return (x << 8) | (x >> 8);
60
0
61
0
#else
62
0
63
0
    return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x);
64
0
65
0
#endif
66
0
}
67
68
inline uint32_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint32_t x ) BOOST_NOEXCEPT
69
0
{
70
0
#ifdef BOOST_ENDIAN_NO_INTRINSICS
71
0
72
0
    uint32_t step16 = x << 16 | x >> 16;
73
0
    return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
74
0
75
0
#else
76
0
77
0
    return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x);
78
0
79
0
#endif
80
0
}
81
82
inline uint64_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint64_t x ) BOOST_NOEXCEPT
83
0
{
84
0
#ifdef BOOST_ENDIAN_NO_INTRINSICS
85
0
86
0
    uint64_t step32 = x << 32 | x >> 32;
87
0
    uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
88
0
    return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
89
0
90
0
#else
91
0
92
0
    return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x);
93
0
94
0
# endif
95
0
}
96
97
#if defined(BOOST_HAS_INT128)
98
99
inline uint128_type BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint128_type x ) BOOST_NOEXCEPT
100
0
{
101
0
    return endian_reverse_impl( static_cast<uint64_t>( x >> 64 ) ) |
102
0
        static_cast<uint128_type>( endian_reverse_impl( static_cast<uint64_t>( x ) ) ) << 64;
103
0
}
104
105
#endif
106
107
// is_endian_reversible
108
109
template<class T> struct is_endian_reversible: boost::integral_constant<bool,
110
    (boost::is_integral<T>::value && !boost::is_same<T, bool>::value) || is_scoped_enum<T>::value>
111
{
112
};
113
114
// is_endian_reversible_inplace
115
116
template<class T> struct is_endian_reversible_inplace: boost::integral_constant<bool,
117
    boost::is_integral<T>::value || boost::is_enum<T>::value || boost::is_same<T, float>::value || boost::is_same<T, double>::value>
118
{
119
};
120
121
} // namespace detail
122
123
// Requires:
124
//   T is non-bool integral or scoped enumeration type
125
126
template<class T> inline BOOST_CONSTEXPR
127
    typename enable_if_< !is_class<T>::value, T >::type
128
    endian_reverse( T x ) BOOST_NOEXCEPT
129
{
130
    BOOST_STATIC_ASSERT( detail::is_endian_reversible<T>::value );
131
132
    typedef typename detail::integral_by_size< sizeof(T) >::type uintN_t;
133
134
    return static_cast<T>( detail::endian_reverse_impl( static_cast<uintN_t>( x ) ) );
135
}
136
137
// Requires:
138
//   T is integral, enumeration, float or double
139
140
template<class T> inline
141
    typename enable_if_< !is_class<T>::value >::type
142
    endian_reverse_inplace( T & x ) BOOST_NOEXCEPT
143
0
{
144
0
    BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<T>::value );
145
0
146
0
    typename detail::integral_by_size< sizeof(T) >::type x2;
147
0
148
0
    std::memcpy( &x2, &x, sizeof(T) );
149
0
150
0
    x2 = detail::endian_reverse_impl( x2 );
151
0
152
0
    std::memcpy( &x, &x2, sizeof(T) );
153
0
}
Unexecuted instantiation: _ZN5boost6endian22endian_reverse_inplaceItEENS_10enable_if_IXntsr8is_classIT_EE5valueEvE4typeERS3_
Unexecuted instantiation: _ZN5boost6endian22endian_reverse_inplaceIjEENS_10enable_if_IXntsr8is_classIT_EE5valueEvE4typeERS3_
Unexecuted instantiation: _ZN5boost6endian22endian_reverse_inplaceIyEENS_10enable_if_IXntsr8is_classIT_EE5valueEvE4typeERS3_
154
155
// Default implementation for user-defined types
156
157
template<class T> inline
158
    typename enable_if_< is_class<T>::value >::type
159
    endian_reverse_inplace( T & x ) BOOST_NOEXCEPT
160
{
161
    x = endian_reverse( x );
162
}
163
164
// endian_reverse_inplace for arrays
165
166
template<class T, std::size_t N>
167
inline void endian_reverse_inplace( T (&x)[ N ] ) BOOST_NOEXCEPT
168
{
169
    for( std::size_t i = 0; i < N; ++i )
170
    {
171
        endian_reverse_inplace( x[i] );
172
    }
173
}
174
175
} // namespace endian
176
} // namespace boost
177
178
#endif  // BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/endian/detail/endian_store.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef BOOST_ENDIAN_DETAIL_ENDIAN_STORE_HPP_INCLUDED
2
#define BOOST_ENDIAN_DETAIL_ENDIAN_STORE_HPP_INCLUDED
3
4
// Copyright 2019 Peter Dimov
5
//
6
// Distributed under the Boost Software License, Version 1.0.
7
// http://www.boost.org/LICENSE_1_0.txt
8
9
#include <boost/endian/detail/endian_reverse.hpp>
10
#include <boost/endian/detail/order.hpp>
11
#include <boost/endian/detail/integral_by_size.hpp>
12
#include <boost/endian/detail/is_trivially_copyable.hpp>
13
#include <boost/type_traits/is_integral.hpp>
14
#include <boost/type_traits/is_enum.hpp>
15
#include <boost/static_assert.hpp>
16
#include <cstddef>
17
#include <cstring>
18
19
namespace boost
20
{
21
namespace endian
22
{
23
24
namespace detail
25
{
26
27
template<class T, std::size_t N1, BOOST_SCOPED_ENUM(order) O1, std::size_t N2, BOOST_SCOPED_ENUM(order) O2> struct endian_store_impl
28
{
29
};
30
31
} // namespace detail
32
33
// Requires:
34
//
35
//    sizeof(T) must be 1, 2, 4, or 8
36
//    1 <= N <= sizeof(T)
37
//    T is TriviallyCopyable
38
//    if N < sizeof(T), T is integral or enum
39
40
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) Order>
41
inline void endian_store( unsigned char * p, T const & v ) BOOST_NOEXCEPT
42
0
{
43
0
    BOOST_STATIC_ASSERT( sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8 );
44
0
    BOOST_STATIC_ASSERT( N >= 1 && N <= sizeof(T) );
45
0
46
0
    return detail::endian_store_impl<T, sizeof(T), order::native, N, Order>()( p, v );
47
0
}
Unexecuted instantiation: _ZN5boost6endian12endian_storeIsLm2ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeItLm2ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIsLm2ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeItLm2ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIiLm3ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIjLm3ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIiLm3ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIjLm3ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIiLm4ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIjLm4ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIiLm4ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIjLm4ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIxLm5ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIyLm5ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIxLm5ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIyLm5ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIxLm6ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIyLm6ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIxLm6ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIyLm6ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIxLm7ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIyLm7ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIxLm7ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIyLm7ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIxLm8ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIyLm8ELNS0_5orderE1EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIxLm8ELNS0_5orderE0EEEvPhRKT_
Unexecuted instantiation: _ZN5boost6endian12endian_storeIyLm8ELNS0_5orderE0EEEvPhRKT_
48
49
namespace detail
50
{
51
52
// same endianness, same size
53
54
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O> struct endian_store_impl<T, N, O, N, O>
55
{
56
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
57
0
    {
58
0
        BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
59
0
60
0
        std::memcpy( p, &v, N );
61
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIsLm2ELNS0_5orderE1ELm2ELS3_1EEclEPhRKs
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implItLm2ELNS0_5orderE1ELm2ELS3_1EEclEPhRKt
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIiLm4ELNS0_5orderE1ELm4ELS3_1EEclEPhRKi
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIjLm4ELNS0_5orderE1ELm4ELS3_1EEclEPhRKj
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIxLm8ELNS0_5orderE1ELm8ELS3_1EEclEPhRKx
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIyLm8ELNS0_5orderE1ELm8ELS3_1EEclEPhRKy
62
};
63
64
// same size, reverse endianness
65
66
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O1, BOOST_SCOPED_ENUM(order) O2> struct endian_store_impl<T, N, O1, N, O2>
67
{
68
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
69
0
    {
70
0
        BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
71
0
72
0
        typename integral_by_size<N>::type tmp;
73
0
        std::memcpy( &tmp, &v, N );
74
0
75
0
        endian_reverse_inplace( tmp );
76
0
77
0
        std::memcpy( p, &tmp, N );
78
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIsLm2ELNS0_5orderE1ELm2ELS3_0EEclEPhRKs
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implItLm2ELNS0_5orderE1ELm2ELS3_0EEclEPhRKt
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIiLm4ELNS0_5orderE1ELm4ELS3_0EEclEPhRKi
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIjLm4ELNS0_5orderE1ELm4ELS3_0EEclEPhRKj
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIxLm8ELNS0_5orderE1ELm8ELS3_0EEclEPhRKx
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIyLm8ELNS0_5orderE1ELm8ELS3_0EEclEPhRKy
79
};
80
81
// truncating store 2 -> 1
82
83
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 2, Order, 1, order::little>
84
{
85
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
86
    {
87
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
88
89
        unsigned char tmp[ 2 ];
90
        boost::endian::endian_store<T, 2, order::little>( tmp, v );
91
92
        p[0] = tmp[0];
93
    }
94
};
95
96
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 2, Order, 1, order::big>
97
{
98
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
99
    {
100
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
101
102
        unsigned char tmp[ 2 ];
103
        boost::endian::endian_store<T, 2, order::big>( tmp, v );
104
105
        p[0] = tmp[1];
106
    }
107
};
108
109
// truncating store 4 -> 1
110
111
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 1, order::little>
112
{
113
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
114
    {
115
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
116
117
        unsigned char tmp[ 4 ];
118
        boost::endian::endian_store<T, 4, order::little>( tmp, v );
119
120
        p[0] = tmp[0];
121
    }
122
};
123
124
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 1, order::big>
125
{
126
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
127
    {
128
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
129
130
        unsigned char tmp[ 4 ];
131
        boost::endian::endian_store<T, 4, order::big>( tmp, v );
132
133
        p[0] = tmp[3];
134
    }
135
};
136
137
// truncating store 4 -> 2
138
139
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 2, order::little>
140
{
141
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
142
    {
143
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
144
145
        unsigned char tmp[ 4 ];
146
        boost::endian::endian_store<T, 4, order::little>( tmp, v );
147
148
        p[0] = tmp[0];
149
        p[1] = tmp[1];
150
    }
151
};
152
153
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 2, order::big>
154
{
155
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
156
    {
157
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
158
159
        unsigned char tmp[ 4 ];
160
        boost::endian::endian_store<T, 4, order::big>( tmp, v );
161
162
        p[0] = tmp[2];
163
        p[1] = tmp[3];
164
    }
165
};
166
167
// truncating store 4 -> 3
168
169
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 3, order::little>
170
{
171
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
172
0
    {
173
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
174
0
175
0
        unsigned char tmp[ 4 ];
176
0
        boost::endian::endian_store<T, 4, order::little>( tmp, v );
177
0
178
0
        p[0] = tmp[0];
179
0
        p[1] = tmp[1];
180
0
        p[2] = tmp[2];
181
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIiLm4ELNS0_5orderE1ELm3ELS3_1EEclEPhRKi
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIjLm4ELNS0_5orderE1ELm3ELS3_1EEclEPhRKj
182
};
183
184
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 3, order::big>
185
{
186
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
187
0
    {
188
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
189
0
190
0
        unsigned char tmp[ 4 ];
191
0
        boost::endian::endian_store<T, 4, order::big>( tmp, v );
192
0
193
0
        p[0] = tmp[1];
194
0
        p[1] = tmp[2];
195
0
        p[2] = tmp[3];
196
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIiLm4ELNS0_5orderE1ELm3ELS3_0EEclEPhRKi
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIjLm4ELNS0_5orderE1ELm3ELS3_0EEclEPhRKj
197
};
198
199
// truncating store 8 -> 1
200
201
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 1, order::little>
202
{
203
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
204
    {
205
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
206
207
        unsigned char tmp[ 8 ];
208
        boost::endian::endian_store<T, 8, order::little>( tmp, v );
209
210
        p[0] = tmp[0];
211
    }
212
};
213
214
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 1, order::big>
215
{
216
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
217
    {
218
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
219
220
        unsigned char tmp[ 8 ];
221
        boost::endian::endian_store<T, 8, order::big>( tmp, v );
222
223
        p[0] = tmp[7];
224
    }
225
};
226
227
// truncating store 8 -> 2
228
229
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 2, order::little>
230
{
231
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
232
    {
233
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
234
235
        unsigned char tmp[ 8 ];
236
        boost::endian::endian_store<T, 8, order::little>( tmp, v );
237
238
        p[0] = tmp[0];
239
        p[1] = tmp[1];
240
    }
241
};
242
243
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 2, order::big>
244
{
245
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
246
    {
247
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
248
249
        unsigned char tmp[ 8 ];
250
        boost::endian::endian_store<T, 8, order::big>( tmp, v );
251
252
        p[0] = tmp[6];
253
        p[1] = tmp[7];
254
    }
255
};
256
257
// truncating store 8 -> 3
258
259
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 3, order::little>
260
{
261
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
262
    {
263
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
264
265
        unsigned char tmp[ 8 ];
266
        boost::endian::endian_store<T, 8, order::little>( tmp, v );
267
268
        p[0] = tmp[0];
269
        p[1] = tmp[1];
270
        p[2] = tmp[2];
271
    }
272
};
273
274
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 3, order::big>
275
{
276
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
277
    {
278
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
279
280
        unsigned char tmp[ 8 ];
281
        boost::endian::endian_store<T, 8, order::big>( tmp, v );
282
283
        p[0] = tmp[5];
284
        p[1] = tmp[6];
285
        p[2] = tmp[7];
286
    }
287
};
288
289
// truncating store 8 -> 4
290
291
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 4, order::little>
292
{
293
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
294
    {
295
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
296
297
        unsigned char tmp[ 8 ];
298
        boost::endian::endian_store<T, 8, order::little>( tmp, v );
299
300
        p[0] = tmp[0];
301
        p[1] = tmp[1];
302
        p[2] = tmp[2];
303
        p[3] = tmp[3];
304
    }
305
};
306
307
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 4, order::big>
308
{
309
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
310
    {
311
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
312
313
        unsigned char tmp[ 8 ];
314
        boost::endian::endian_store<T, 8, order::big>( tmp, v );
315
316
        p[0] = tmp[4];
317
        p[1] = tmp[5];
318
        p[2] = tmp[6];
319
        p[3] = tmp[7];
320
    }
321
};
322
323
// truncating store 8 -> 5
324
325
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 5, order::little>
326
{
327
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
328
0
    {
329
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
330
0
331
0
        unsigned char tmp[ 8 ];
332
0
        boost::endian::endian_store<T, 8, order::little>( tmp, v );
333
0
334
0
        p[0] = tmp[0];
335
0
        p[1] = tmp[1];
336
0
        p[2] = tmp[2];
337
0
        p[3] = tmp[3];
338
0
        p[4] = tmp[4];
339
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIxLm8ELNS0_5orderE1ELm5ELS3_1EEclEPhRKx
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIyLm8ELNS0_5orderE1ELm5ELS3_1EEclEPhRKy
340
};
341
342
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 5, order::big>
343
{
344
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
345
0
    {
346
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
347
0
348
0
        unsigned char tmp[ 8 ];
349
0
        boost::endian::endian_store<T, 8, order::big>( tmp, v );
350
0
351
0
        p[0] = tmp[3];
352
0
        p[1] = tmp[4];
353
0
        p[2] = tmp[5];
354
0
        p[3] = tmp[6];
355
0
        p[4] = tmp[7];
356
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIxLm8ELNS0_5orderE1ELm5ELS3_0EEclEPhRKx
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIyLm8ELNS0_5orderE1ELm5ELS3_0EEclEPhRKy
357
};
358
359
// truncating store 8 -> 6
360
361
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 6, order::little>
362
{
363
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
364
0
    {
365
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
366
0
367
0
        unsigned char tmp[ 8 ];
368
0
        boost::endian::endian_store<T, 8, order::little>( tmp, v );
369
0
370
0
        p[0] = tmp[0];
371
0
        p[1] = tmp[1];
372
0
        p[2] = tmp[2];
373
0
        p[3] = tmp[3];
374
0
        p[4] = tmp[4];
375
0
        p[5] = tmp[5];
376
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIxLm8ELNS0_5orderE1ELm6ELS3_1EEclEPhRKx
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIyLm8ELNS0_5orderE1ELm6ELS3_1EEclEPhRKy
377
};
378
379
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 6, order::big>
380
{
381
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
382
0
    {
383
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
384
0
385
0
        unsigned char tmp[ 8 ];
386
0
        boost::endian::endian_store<T, 8, order::big>( tmp, v );
387
0
388
0
        p[0] = tmp[2];
389
0
        p[1] = tmp[3];
390
0
        p[2] = tmp[4];
391
0
        p[3] = tmp[5];
392
0
        p[4] = tmp[6];
393
0
        p[5] = tmp[7];
394
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIxLm8ELNS0_5orderE1ELm6ELS3_0EEclEPhRKx
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIyLm8ELNS0_5orderE1ELm6ELS3_0EEclEPhRKy
395
};
396
397
// truncating store 8 -> 7
398
399
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 7, order::little>
400
{
401
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
402
0
    {
403
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
404
0
405
0
        unsigned char tmp[ 8 ];
406
0
        boost::endian::endian_store<T, 8, order::little>( tmp, v );
407
0
408
0
        p[0] = tmp[0];
409
0
        p[1] = tmp[1];
410
0
        p[2] = tmp[2];
411
0
        p[3] = tmp[3];
412
0
        p[4] = tmp[4];
413
0
        p[5] = tmp[5];
414
0
        p[6] = tmp[6];
415
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIxLm8ELNS0_5orderE1ELm7ELS3_1EEclEPhRKx
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIyLm8ELNS0_5orderE1ELm7ELS3_1EEclEPhRKy
416
};
417
418
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 7, order::big>
419
{
420
    inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
421
0
    {
422
0
        BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
423
0
424
0
        unsigned char tmp[ 8 ];
425
0
        boost::endian::endian_store<T, 8, order::big>( tmp, v );
426
0
427
0
        p[0] = tmp[1];
428
0
        p[1] = tmp[2];
429
0
        p[2] = tmp[3];
430
0
        p[3] = tmp[4];
431
0
        p[4] = tmp[5];
432
0
        p[5] = tmp[6];
433
0
        p[6] = tmp[7];
434
0
    }
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIxLm8ELNS0_5orderE1ELm7ELS3_0EEclEPhRKx
Unexecuted instantiation: _ZNK5boost6endian6detail17endian_store_implIyLm8ELNS0_5orderE1ELm7ELS3_0EEclEPhRKy
435
};
436
437
} // namespace detail
438
439
} // namespace endian
440
} // namespace boost
441
442
#endif  // BOOST_ENDIAN_DETAIL_ENDIAN_STORE_HPP_INCLUDED
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/function/function_base.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Function library
2
3
//  Copyright Douglas Gregor 2001-2006
4
//  Copyright Emil Dotchevski 2007
5
//  Use, modification and distribution is subject to the Boost Software License, Version 1.0.
6
//  (See accompanying file LICENSE_1_0.txt or copy at
7
//  http://www.boost.org/LICENSE_1_0.txt)
8
9
// For more information, see http://www.boost.org
10
11
#ifndef BOOST_FUNCTION_BASE_HEADER
12
#define BOOST_FUNCTION_BASE_HEADER
13
14
#include <stdexcept>
15
#include <string>
16
#include <memory>
17
#include <new>
18
#include <boost/config.hpp>
19
#include <boost/assert.hpp>
20
#include <boost/integer.hpp>
21
#include <boost/type_index.hpp>
22
#include <boost/type_traits/has_trivial_copy.hpp>
23
#include <boost/type_traits/has_trivial_destructor.hpp>
24
#include <boost/type_traits/is_const.hpp>
25
#include <boost/type_traits/is_integral.hpp>
26
#include <boost/type_traits/is_volatile.hpp>
27
#include <boost/type_traits/composite_traits.hpp>
28
#include <boost/ref.hpp>
29
#include <boost/type_traits/conditional.hpp>
30
#include <boost/config/workaround.hpp>
31
#include <boost/type_traits/alignment_of.hpp>
32
#ifndef BOOST_NO_SFINAE
33
#include <boost/type_traits/enable_if.hpp>
34
#else
35
#include <boost/type_traits/integral_constant.hpp>
36
#endif
37
#include <boost/function_equal.hpp>
38
#include <boost/function/function_fwd.hpp>
39
40
#if defined(BOOST_MSVC)
41
#   pragma warning( push )
42
#   pragma warning( disable : 4793 ) // complaint about native code generation
43
#   pragma warning( disable : 4127 ) // "conditional expression is constant"
44
#endif
45
46
#if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG)
47
#  define BOOST_FUNCTION_TARGET_FIX(x) x
48
#else
49
#  define BOOST_FUNCTION_TARGET_FIX(x)
50
#endif // __ICL etc
51
52
#  define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type)              \
53
      typename ::boost::enable_if_<          \
54
                           !(::boost::is_integral<Functor>::value), \
55
                           Type>::type
56
57
namespace boost {
58
  namespace detail {
59
    namespace function {
60
      class X;
61
62
      /**
63
       * A buffer used to store small function objects in
64
       * boost::function. It is a union containing function pointers,
65
       * object pointers, and a structure that resembles a bound
66
       * member function pointer.
67
       */
68
      union function_buffer_members
69
      {
70
        // For pointers to function objects
71
        typedef void* obj_ptr_t;
72
        mutable obj_ptr_t obj_ptr;
73
74
        // For pointers to std::type_info objects
75
        struct type_t {
76
          // (get_functor_type_tag, check_functor_type_tag).
77
          const boost::typeindex::type_info* type;
78
79
          // Whether the type is const-qualified.
80
          bool const_qualified;
81
          // Whether the type is volatile-qualified.
82
          bool volatile_qualified;
83
        } type;
84
85
        // For function pointers of all kinds
86
        typedef void (*func_ptr_t)();
87
        mutable func_ptr_t func_ptr;
88
89
        // For bound member pointers
90
        struct bound_memfunc_ptr_t {
91
          void (X::*memfunc_ptr)(int);
92
          void* obj_ptr;
93
        } bound_memfunc_ptr;
94
95
        // For references to function objects. We explicitly keep
96
        // track of the cv-qualifiers on the object referenced.
97
        struct obj_ref_t {
98
          mutable void* obj_ptr;
99
          bool is_const_qualified;
100
          bool is_volatile_qualified;
101
        } obj_ref;
102
      };
103
104
      union BOOST_SYMBOL_VISIBLE function_buffer
105
      {
106
        // Type-specific union members
107
        mutable function_buffer_members members;
108
109
        // To relax aliasing constraints
110
        mutable char data[sizeof(function_buffer_members)];
111
      };
112
113
      /**
114
       * The unusable class is a placeholder for unused function arguments
115
       * It is also completely unusable except that it constructable from
116
       * anything. This helps compilers without partial specialization to
117
       * handle Boost.Function objects returning void.
118
       */
119
      struct unusable
120
      {
121
0
        unusable() {}
122
        template<typename T> unusable(const T&) {}
123
      };
124
125
      /* Determine the return type. This supports compilers that do not support
126
       * void returns or partial specialization by silently changing the return
127
       * type to "unusable".
128
       */
129
      template<typename T> struct function_return_type { typedef T type; };
130
131
      template<>
132
      struct function_return_type<void>
133
      {
134
        typedef unusable type;
135
      };
136
137
      // The operation type to perform on the given functor/function pointer
138
      enum functor_manager_operation_type {
139
        clone_functor_tag,
140
        move_functor_tag,
141
        destroy_functor_tag,
142
        check_functor_type_tag,
143
        get_functor_type_tag
144
      };
145
146
      // Tags used to decide between different types of functions
147
      struct function_ptr_tag {};
148
      struct function_obj_tag {};
149
      struct member_ptr_tag {};
150
      struct function_obj_ref_tag {};
151
152
      template<typename F>
153
      class get_function_tag
154
      {
155
        typedef typename conditional<(is_pointer<F>::value),
156
                                   function_ptr_tag,
157
                                   function_obj_tag>::type ptr_or_obj_tag;
158
159
        typedef typename conditional<(is_member_pointer<F>::value),
160
                                   member_ptr_tag,
161
                                   ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
162
163
        typedef typename conditional<(is_reference_wrapper<F>::value),
164
                                   function_obj_ref_tag,
165
                                   ptr_or_obj_or_mem_tag>::type or_ref_tag;
166
167
      public:
168
        typedef or_ref_tag type;
169
      };
170
171
      // The trivial manager does nothing but return the same pointer (if we
172
      // are cloning) or return the null pointer (if we are deleting).
173
      template<typename F>
174
      struct reference_manager
175
      {
176
        static inline void
177
        manage(const function_buffer& in_buffer, function_buffer& out_buffer,
178
               functor_manager_operation_type op)
179
        {
180
          switch (op) {
181
          case clone_functor_tag:
182
            out_buffer.members.obj_ref = in_buffer.members.obj_ref;
183
            return;
184
185
          case move_functor_tag:
186
            out_buffer.members.obj_ref = in_buffer.members.obj_ref;
187
            in_buffer.members.obj_ref.obj_ptr = 0;
188
            return;
189
190
          case destroy_functor_tag:
191
            out_buffer.members.obj_ref.obj_ptr = 0;
192
            return;
193
194
          case check_functor_type_tag:
195
            {
196
              // Check whether we have the same type. We can add
197
              // cv-qualifiers, but we can't take them away.
198
              if (*out_buffer.members.type.type == boost::typeindex::type_id<F>()
199
                  && (!in_buffer.members.obj_ref.is_const_qualified
200
                      || out_buffer.members.type.const_qualified)
201
                  && (!in_buffer.members.obj_ref.is_volatile_qualified
202
                      || out_buffer.members.type.volatile_qualified))
203
                out_buffer.members.obj_ptr = in_buffer.members.obj_ref.obj_ptr;
204
              else
205
                out_buffer.members.obj_ptr = 0;
206
            }
207
            return;
208
209
          case get_functor_type_tag:
210
            out_buffer.members.type.type = &boost::typeindex::type_id<F>().type_info();
211
            out_buffer.members.type.const_qualified = in_buffer.members.obj_ref.is_const_qualified;
212
            out_buffer.members.type.volatile_qualified = in_buffer.members.obj_ref.is_volatile_qualified;
213
            return;
214
          }
215
        }
216
      };
217
218
      /**
219
       * Determine if boost::function can use the small-object
220
       * optimization with the function object type F.
221
       */
222
      template<typename F>
223
      struct function_allows_small_object_optimization
224
      {
225
        BOOST_STATIC_CONSTANT
226
          (bool,
227
           value = ((sizeof(F) <= sizeof(function_buffer) &&
228
                     (alignment_of<function_buffer>::value
229
                      % alignment_of<F>::value == 0))));
230
      };
231
232
      template <typename F,typename A>
233
      struct functor_wrapper: public F, public A
234
      {
235
        functor_wrapper( F f, A a ):
236
          F(f),
237
          A(a)
238
        {
239
        }
240
241
        functor_wrapper(const functor_wrapper& f) :
242
          F(static_cast<const F&>(f)),
243
          A(static_cast<const A&>(f))
244
        {
245
        }
246
      };
247
248
      /**
249
       * The functor_manager class contains a static function "manage" which
250
       * can clone or destroy the given function/function object pointer.
251
       */
252
      template<typename Functor>
253
      struct functor_manager_common
254
      {
255
        typedef Functor functor_type;
256
257
        // Function pointers
258
        static inline void
259
        manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer,
260
                functor_manager_operation_type op)
261
        {
262
          if (op == clone_functor_tag)
263
            out_buffer.members.func_ptr = in_buffer.members.func_ptr;
264
          else if (op == move_functor_tag) {
265
            out_buffer.members.func_ptr = in_buffer.members.func_ptr;
266
            in_buffer.members.func_ptr = 0;
267
          } else if (op == destroy_functor_tag)
268
            out_buffer.members.func_ptr = 0;
269
          else if (op == check_functor_type_tag) {
270
            if (*out_buffer.members.type.type == boost::typeindex::type_id<Functor>())
271
              out_buffer.members.obj_ptr = &in_buffer.members.func_ptr;
272
            else
273
              out_buffer.members.obj_ptr = 0;
274
          } else /* op == get_functor_type_tag */ {
275
            out_buffer.members.type.type = &boost::typeindex::type_id<Functor>().type_info();
276
            out_buffer.members.type.const_qualified = false;
277
            out_buffer.members.type.volatile_qualified = false;
278
          }
279
        }
280
281
        // Function objects that fit in the small-object buffer.
282
        static inline void
283
        manage_small(const function_buffer& in_buffer, function_buffer& out_buffer,
284
                functor_manager_operation_type op)
285
        {
286
          if (op == clone_functor_tag || op == move_functor_tag) {
287
            const functor_type* in_functor =
288
              reinterpret_cast<const functor_type*>(in_buffer.data);
289
            new (reinterpret_cast<void*>(out_buffer.data)) functor_type(*in_functor);
290
291
            if (op == move_functor_tag) {
292
              functor_type* f = reinterpret_cast<functor_type*>(in_buffer.data);
293
              (void)f; // suppress warning about the value of f not being used (MSVC)
294
              f->~Functor();
295
            }
296
          } else if (op == destroy_functor_tag) {
297
            // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
298
             functor_type* f = reinterpret_cast<functor_type*>(out_buffer.data);
299
             (void)f; // suppress warning about the value of f not being used (MSVC)
300
             f->~Functor();
301
          } else if (op == check_functor_type_tag) {
302
             if (*out_buffer.members.type.type == boost::typeindex::type_id<Functor>())
303
              out_buffer.members.obj_ptr = in_buffer.data;
304
            else
305
              out_buffer.members.obj_ptr = 0;
306
          } else /* op == get_functor_type_tag */ {
307
            out_buffer.members.type.type = &boost::typeindex::type_id<Functor>().type_info();
308
            out_buffer.members.type.const_qualified = false;
309
            out_buffer.members.type.volatile_qualified = false;
310
          }
311
        }
312
      };
313
314
      template<typename Functor>
315
      struct functor_manager
316
      {
317
      private:
318
        typedef Functor functor_type;
319
320
        // Function pointers
321
        static inline void
322
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
323
                functor_manager_operation_type op, function_ptr_tag)
324
        {
325
          functor_manager_common<Functor>::manage_ptr(in_buffer,out_buffer,op);
326
        }
327
328
        // Function objects that fit in the small-object buffer.
329
        static inline void
330
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
331
                functor_manager_operation_type op, true_type)
332
        {
333
          functor_manager_common<Functor>::manage_small(in_buffer,out_buffer,op);
334
        }
335
336
        // Function objects that require heap allocation
337
        static inline void
338
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
339
                functor_manager_operation_type op, false_type)
340
30
        {
341
30
          if (op == clone_functor_tag) {
342
            // Clone the functor
343
            // GCC 2.95.3 gets the CV qualifiers wrong here, so we
344
            // can't do the static_cast that we should do.
345
            // jewillco: Changing this to static_cast because GCC 2.95.3 is
346
            // obsolete.
347
12
            const functor_type* f =
348
12
              static_cast<const functor_type*>(in_buffer.members.obj_ptr);
349
12
            functor_type* new_f = new functor_type(*f);
350
12
            out_buffer.members.obj_ptr = new_f;
351
18
          } else if (op == move_functor_tag) {
352
0
            out_buffer.members.obj_ptr = in_buffer.members.obj_ptr;
353
0
            in_buffer.members.obj_ptr = 0;
354
18
          } else if (op == destroy_functor_tag) {
355
            /* Cast from the void pointer to the functor pointer type */
356
18
            functor_type* f =
357
18
              static_cast<functor_type*>(out_buffer.members.obj_ptr);
358
18
            delete f;
359
18
            out_buffer.members.obj_ptr = 0;
360
18
          } else if (op == check_functor_type_tag) {
361
0
            if (*out_buffer.members.type.type == boost::typeindex::type_id<Functor>())
362
0
              out_buffer.members.obj_ptr = in_buffer.members.obj_ptr;
363
0
            else
364
0
              out_buffer.members.obj_ptr = 0;
365
0
          } else /* op == get_functor_type_tag */ {
366
0
            out_buffer.members.type.type = &boost::typeindex::type_id<Functor>().type_info();
367
0
            out_buffer.members.type.const_qualified = false;
368
0
            out_buffer.members.type.volatile_qualified = false;
369
0
          }
370
30
        }
371
372
        // For function objects, we determine whether the function
373
        // object can use the small-object optimization buffer or
374
        // whether we need to allocate it on the heap.
375
        static inline void
376
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
377
                functor_manager_operation_type op, function_obj_tag)
378
30
        {
379
30
          manager(in_buffer, out_buffer, op,
380
30
                  integral_constant<bool, (function_allows_small_object_optimization<functor_type>::value)>());
381
30
        }
382
383
        // For member pointers, we use the small-object optimization buffer.
384
        static inline void
385
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
386
                functor_manager_operation_type op, member_ptr_tag)
387
        {
388
          manager(in_buffer, out_buffer, op, true_type());
389
        }
390
391
      public:
392
        /* Dispatch to an appropriate manager based on whether we have a
393
           function pointer or a function object pointer. */
394
        static inline void
395
        manage(const function_buffer& in_buffer, function_buffer& out_buffer,
396
               functor_manager_operation_type op)
397
30
        {
398
30
          typedef typename get_function_tag<functor_type>::type tag_type;
399
30
          if (op == get_functor_type_tag) {
400
0
            out_buffer.members.type.type = &boost::typeindex::type_id<functor_type>().type_info();
401
0
            out_buffer.members.type.const_qualified = false;
402
0
            out_buffer.members.type.volatile_qualified = false;
403
30
          } else {
404
30
            manager(in_buffer, out_buffer, op, tag_type());
405
30
          }
406
30
        }
407
      };
408
409
      template<typename Functor, typename Allocator>
410
      struct functor_manager_a
411
      {
412
      private:
413
        typedef Functor functor_type;
414
415
        // Function pointers
416
        static inline void
417
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
418
                functor_manager_operation_type op, function_ptr_tag)
419
        {
420
          functor_manager_common<Functor>::manage_ptr(in_buffer,out_buffer,op);
421
        }
422
423
        // Function objects that fit in the small-object buffer.
424
        static inline void
425
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
426
                functor_manager_operation_type op, true_type)
427
        {
428
          functor_manager_common<Functor>::manage_small(in_buffer,out_buffer,op);
429
        }
430
431
        // Function objects that require heap allocation
432
        static inline void
433
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
434
                functor_manager_operation_type op, false_type)
435
        {
436
          typedef functor_wrapper<Functor,Allocator> functor_wrapper_type;
437
#if defined(BOOST_NO_CXX11_ALLOCATOR)
438
          typedef typename Allocator::template rebind<functor_wrapper_type>::other
439
            wrapper_allocator_type;
440
          typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
441
#else
442
          using wrapper_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<functor_wrapper_type>;
443
          using wrapper_allocator_pointer_type = typename std::allocator_traits<wrapper_allocator_type>::pointer;
444
#endif
445
446
          if (op == clone_functor_tag) {
447
            // Clone the functor
448
            // GCC 2.95.3 gets the CV qualifiers wrong here, so we
449
            // can't do the static_cast that we should do.
450
            const functor_wrapper_type* f =
451
              static_cast<const functor_wrapper_type*>(in_buffer.members.obj_ptr);
452
            wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*f));
453
            wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
454
#if defined(BOOST_NO_CXX11_ALLOCATOR)
455
            wrapper_allocator.construct(copy, *f);
456
#else
457
            std::allocator_traits<wrapper_allocator_type>::construct(wrapper_allocator, copy, *f);
458
#endif
459
460
            // Get back to the original pointer type
461
            functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
462
            out_buffer.members.obj_ptr = new_f;
463
          } else if (op == move_functor_tag) {
464
            out_buffer.members.obj_ptr = in_buffer.members.obj_ptr;
465
            in_buffer.members.obj_ptr = 0;
466
          } else if (op == destroy_functor_tag) {
467
            /* Cast from the void pointer to the functor_wrapper_type */
468
            functor_wrapper_type* victim =
469
              static_cast<functor_wrapper_type*>(in_buffer.members.obj_ptr);
470
            wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*victim));
471
#if defined(BOOST_NO_CXX11_ALLOCATOR)
472
            wrapper_allocator.destroy(victim);
473
#else
474
            std::allocator_traits<wrapper_allocator_type>::destroy(wrapper_allocator, victim);
475
#endif
476
            wrapper_allocator.deallocate(victim,1);
477
            out_buffer.members.obj_ptr = 0;
478
          } else if (op == check_functor_type_tag) {
479
            if (*out_buffer.members.type.type == boost::typeindex::type_id<Functor>())
480
              out_buffer.members.obj_ptr = in_buffer.members.obj_ptr;
481
            else
482
              out_buffer.members.obj_ptr = 0;
483
          } else /* op == get_functor_type_tag */ {
484
            out_buffer.members.type.type = &boost::typeindex::type_id<Functor>().type_info();
485
            out_buffer.members.type.const_qualified = false;
486
            out_buffer.members.type.volatile_qualified = false;
487
          }
488
        }
489
490
        // For function objects, we determine whether the function
491
        // object can use the small-object optimization buffer or
492
        // whether we need to allocate it on the heap.
493
        static inline void
494
        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
495
                functor_manager_operation_type op, function_obj_tag)
496
        {
497
          manager(in_buffer, out_buffer, op,
498
                  integral_constant<bool, (function_allows_small_object_optimization<functor_type>::value)>());
499
        }
500
501
      public:
502
        /* Dispatch to an appropriate manager based on whether we have a
503
           function pointer or a function object pointer. */
504
        static inline void
505
        manage(const function_buffer& in_buffer, function_buffer& out_buffer,
506
               functor_manager_operation_type op)
507
        {
508
          typedef typename get_function_tag<functor_type>::type tag_type;
509
          if (op == get_functor_type_tag) {
510
            out_buffer.members.type.type = &boost::typeindex::type_id<functor_type>().type_info();
511
            out_buffer.members.type.const_qualified = false;
512
            out_buffer.members.type.volatile_qualified = false;
513
          } else {
514
            manager(in_buffer, out_buffer, op, tag_type());
515
          }
516
        }
517
      };
518
519
      // A type that is only used for comparisons against zero
520
      struct useless_clear_type {};
521
522
#ifdef BOOST_NO_SFINAE
523
      // These routines perform comparisons between a Boost.Function
524
      // object and an arbitrary function object (when the last
525
      // parameter is false_type) or against zero (when the
526
      // last parameter is true_type). They are only necessary
527
      // for compilers that don't support SFINAE.
528
      template<typename Function, typename Functor>
529
        bool
530
        compare_equal(const Function& f, const Functor&, int, true_type)
531
        { return f.empty(); }
532
533
      template<typename Function, typename Functor>
534
        bool
535
        compare_not_equal(const Function& f, const Functor&, int,
536
                          true_type)
537
        { return !f.empty(); }
538
539
      template<typename Function, typename Functor>
540
        bool
541
        compare_equal(const Function& f, const Functor& g, long,
542
                      false_type)
543
        {
544
          if (const Functor* fp = f.template target<Functor>())
545
            return function_equal(*fp, g);
546
          else return false;
547
        }
548
549
      template<typename Function, typename Functor>
550
        bool
551
        compare_equal(const Function& f, const reference_wrapper<Functor>& g,
552
                      int, false_type)
553
        {
554
          if (const Functor* fp = f.template target<Functor>())
555
            return fp == g.get_pointer();
556
          else return false;
557
        }
558
559
      template<typename Function, typename Functor>
560
        bool
561
        compare_not_equal(const Function& f, const Functor& g, long,
562
                          false_type)
563
        {
564
          if (const Functor* fp = f.template target<Functor>())
565
            return !function_equal(*fp, g);
566
          else return true;
567
        }
568
569
      template<typename Function, typename Functor>
570
        bool
571
        compare_not_equal(const Function& f,
572
                          const reference_wrapper<Functor>& g, int,
573
                          false_type)
574
        {
575
          if (const Functor* fp = f.template target<Functor>())
576
            return fp != g.get_pointer();
577
          else return true;
578
        }
579
#endif // BOOST_NO_SFINAE
580
581
      /**
582
       * Stores the "manager" portion of the vtable for a
583
       * boost::function object.
584
       */
585
      struct vtable_base
586
      {
587
        void (*manager)(const function_buffer& in_buffer,
588
                        function_buffer& out_buffer,
589
                        functor_manager_operation_type op);
590
      };
591
    } // end namespace function
592
  } // end namespace detail
593
594
/**
595
 * The function_base class contains the basic elements needed for the
596
 * function1, function2, function3, etc. classes. It is common to all
597
 * functions (and as such can be used to tell if we have one of the
598
 * functionN objects).
599
 */
600
class function_base
601
{
602
public:
603
36
  function_base() : vtable(0) { }
604
605
  /** Determine if the function is empty (i.e., has no target). */
606
264
  bool empty() const { return !vtable; }
607
608
  /** Retrieve the type of the stored function object, or type_id<void>()
609
      if this is empty. */
610
  const boost::typeindex::type_info& target_type() const
611
0
  {
612
0
    if (!vtable) return boost::typeindex::type_id<void>().type_info();
613
0
614
0
    detail::function::function_buffer type;
615
0
    get_vtable()->manager(functor, type, detail::function::get_functor_type_tag);
616
0
    return *type.members.type.type;
617
0
  }
618
619
  template<typename Functor>
620
    Functor* target()
621
    {
622
      if (!vtable) return 0;
623
624
      detail::function::function_buffer type_result;
625
      type_result.members.type.type = &boost::typeindex::type_id<Functor>().type_info();
626
      type_result.members.type.const_qualified = is_const<Functor>::value;
627
      type_result.members.type.volatile_qualified = is_volatile<Functor>::value;
628
      get_vtable()->manager(functor, type_result,
629
                      detail::function::check_functor_type_tag);
630
      return static_cast<Functor*>(type_result.members.obj_ptr);
631
    }
632
633
  template<typename Functor>
634
    const Functor* target() const
635
    {
636
      if (!vtable) return 0;
637
638
      detail::function::function_buffer type_result;
639
      type_result.members.type.type = &boost::typeindex::type_id<Functor>().type_info();
640
      type_result.members.type.const_qualified = true;
641
      type_result.members.type.volatile_qualified = is_volatile<Functor>::value;
642
      get_vtable()->manager(functor, type_result,
643
                      detail::function::check_functor_type_tag);
644
      // GCC 2.95.3 gets the CV qualifiers wrong here, so we
645
      // can't do the static_cast that we should do.
646
      return static_cast<const Functor*>(type_result.members.obj_ptr);
647
    }
648
649
  template<typename F>
650
    bool contains(const F& f) const
651
    {
652
      if (const F* fp = this->template target<F>())
653
      {
654
        return function_equal(*fp, f);
655
      } else {
656
        return false;
657
      }
658
    }
659
660
#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3
661
  // GCC 3.3 and newer cannot copy with the global operator==, due to
662
  // problems with instantiation of function return types before it
663
  // has been verified that the argument types match up.
664
  template<typename Functor>
665
    BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
666
    operator==(Functor g) const
667
    {
668
      if (const Functor* fp = target<Functor>())
669
        return function_equal(*fp, g);
670
      else return false;
671
    }
672
673
  template<typename Functor>
674
    BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
675
    operator!=(Functor g) const
676
    {
677
      if (const Functor* fp = target<Functor>())
678
        return !function_equal(*fp, g);
679
      else return true;
680
    }
681
#endif
682
683
public: // should be protected, but GCC 2.95.3 will fail to allow access
684
0
  detail::function::vtable_base* get_vtable() const {
685
0
    return reinterpret_cast<detail::function::vtable_base*>(
686
0
             reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
687
0
  }
688
689
30
  bool has_trivial_copy_and_destroy() const {
690
30
    return reinterpret_cast<std::size_t>(vtable) & 0x01;
691
30
  }
692
693
  detail::function::vtable_base* vtable;
694
  mutable detail::function::function_buffer functor;
695
};
696
697
#if defined(BOOST_CLANG)
698
#   pragma clang diagnostic push
699
#   pragma clang diagnostic ignored "-Wweak-vtables"
700
#endif
701
/**
702
 * The bad_function_call exception class is thrown when a boost::function
703
 * object is invoked
704
 */
705
class BOOST_SYMBOL_VISIBLE bad_function_call : public std::runtime_error
706
{
707
public:
708
0
  bad_function_call() : std::runtime_error("call to empty boost::function") {}
709
};
710
#if defined(BOOST_CLANG)
711
#   pragma clang diagnostic pop
712
#endif
713
714
#ifndef BOOST_NO_SFINAE
715
inline bool operator==(const function_base& f,
716
                       detail::function::useless_clear_type*)
717
0
{
718
0
  return f.empty();
719
0
}
720
721
inline bool operator!=(const function_base& f,
722
                       detail::function::useless_clear_type*)
723
0
{
724
0
  return !f.empty();
725
0
}
726
727
inline bool operator==(detail::function::useless_clear_type*,
728
                       const function_base& f)
729
0
{
730
0
  return f.empty();
731
0
}
732
733
inline bool operator!=(detail::function::useless_clear_type*,
734
                       const function_base& f)
735
0
{
736
0
  return !f.empty();
737
0
}
738
#endif
739
740
#ifdef BOOST_NO_SFINAE
741
// Comparisons between boost::function objects and arbitrary function objects
742
template<typename Functor>
743
  inline bool operator==(const function_base& f, Functor g)
744
  {
745
    typedef integral_constant<bool, (is_integral<Functor>::value)> integral;
746
    return detail::function::compare_equal(f, g, 0, integral());
747
  }
748
749
template<typename Functor>
750
  inline bool operator==(Functor g, const function_base& f)
751
  {
752
    typedef integral_constant<bool, (is_integral<Functor>::value)> integral;
753
    return detail::function::compare_equal(f, g, 0, integral());
754
  }
755
756
template<typename Functor>
757
  inline bool operator!=(const function_base& f, Functor g)
758
  {
759
    typedef integral_constant<bool, (is_integral<Functor>::value)> integral;
760
    return detail::function::compare_not_equal(f, g, 0, integral());
761
  }
762
763
template<typename Functor>
764
  inline bool operator!=(Functor g, const function_base& f)
765
  {
766
    typedef integral_constant<bool, (is_integral<Functor>::value)> integral;
767
    return detail::function::compare_not_equal(f, g, 0, integral());
768
  }
769
#else
770
771
#  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
772
// Comparisons between boost::function objects and arbitrary function
773
// objects. GCC 3.3 and before has an obnoxious bug that prevents this
774
// from working.
775
template<typename Functor>
776
  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
777
  operator==(const function_base& f, Functor g)
778
  {
779
    if (const Functor* fp = f.template target<Functor>())
780
      return function_equal(*fp, g);
781
    else return false;
782
  }
783
784
template<typename Functor>
785
  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
786
  operator==(Functor g, const function_base& f)
787
  {
788
    if (const Functor* fp = f.template target<Functor>())
789
      return function_equal(g, *fp);
790
    else return false;
791
  }
792
793
template<typename Functor>
794
  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
795
  operator!=(const function_base& f, Functor g)
796
  {
797
    if (const Functor* fp = f.template target<Functor>())
798
      return !function_equal(*fp, g);
799
    else return true;
800
  }
801
802
template<typename Functor>
803
  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
804
  operator!=(Functor g, const function_base& f)
805
  {
806
    if (const Functor* fp = f.template target<Functor>())
807
      return !function_equal(g, *fp);
808
    else return true;
809
  }
810
#  endif
811
812
template<typename Functor>
813
  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
814
  operator==(const function_base& f, reference_wrapper<Functor> g)
815
  {
816
    if (const Functor* fp = f.template target<Functor>())
817
      return fp == g.get_pointer();
818
    else return false;
819
  }
820
821
template<typename Functor>
822
  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
823
  operator==(reference_wrapper<Functor> g, const function_base& f)
824
  {
825
    if (const Functor* fp = f.template target<Functor>())
826
      return g.get_pointer() == fp;
827
    else return false;
828
  }
829
830
template<typename Functor>
831
  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
832
  operator!=(const function_base& f, reference_wrapper<Functor> g)
833
  {
834
    if (const Functor* fp = f.template target<Functor>())
835
      return fp != g.get_pointer();
836
    else return true;
837
  }
838
839
template<typename Functor>
840
  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
841
  operator!=(reference_wrapper<Functor> g, const function_base& f)
842
  {
843
    if (const Functor* fp = f.template target<Functor>())
844
      return g.get_pointer() != fp;
845
    else return true;
846
  }
847
848
#endif // Compiler supporting SFINAE
849
850
namespace detail {
851
  namespace function {
852
    inline bool has_empty_target(const function_base* f)
853
0
    {
854
0
      return f->empty();
855
0
    }
856
857
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
858
    inline bool has_empty_target(const void*)
859
    {
860
      return false;
861
    }
862
#else
863
    inline bool has_empty_target(...)
864
6
    {
865
6
      return false;
866
6
    }
867
#endif
868
  } // end namespace function
869
} // end namespace detail
870
} // end namespace boost
871
872
#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
873
874
#if defined(BOOST_MSVC)
875
#   pragma warning( pop )
876
#endif
877
878
#endif // BOOST_FUNCTION_BASE_HEADER
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/function/function_template.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Function library
2
3
//  Copyright Douglas Gregor 2001-2006
4
//  Copyright Emil Dotchevski 2007
5
//  Use, modification and distribution is subject to the Boost Software License, Version 1.0.
6
//  (See accompanying file LICENSE_1_0.txt or copy at
7
//  http://www.boost.org/LICENSE_1_0.txt)
8
9
// For more information, see http://www.boost.org
10
11
// Note: this header is a header template and must NOT have multiple-inclusion
12
// protection.
13
#include <boost/function/detail/prologue.hpp>
14
#include <boost/core/no_exceptions_support.hpp>
15
16
#if defined(BOOST_MSVC)
17
#   pragma warning( push )
18
#   pragma warning( disable : 4127 ) // "conditional expression is constant"
19
#endif
20
21
#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
22
23
#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
24
25
#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
26
27
#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
28
29
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
30
#   define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
31
#else
32
240
#   define BOOST_FUNCTION_ARG(J,I,D) static_cast<BOOST_PP_CAT(T,I)&&>(BOOST_PP_CAT(a,I))
33
240
#   define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY)
34
#endif
35
36
#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
37
  typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
38
39
#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
40
41
// Comma if nonzero number of arguments
42
#if BOOST_FUNCTION_NUM_ARGS == 0
43
#  define BOOST_FUNCTION_COMMA
44
#else
45
#  define BOOST_FUNCTION_COMMA ,
46
#endif // BOOST_FUNCTION_NUM_ARGS > 0
47
48
// Class names used in this version of the code
49
#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
50
#define BOOST_FUNCTION_FUNCTION_INVOKER \
51
  BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
52
#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
53
  BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
54
#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
55
  BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
56
#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
57
  BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
58
#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
59
  BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
60
#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
61
  BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
62
#define BOOST_FUNCTION_MEMBER_INVOKER \
63
  BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
64
#define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
65
  BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
66
#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
67
  BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
68
#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
69
  BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
70
#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
71
  BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
72
#define BOOST_FUNCTION_GET_MEMBER_INVOKER \
73
  BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
74
#define BOOST_FUNCTION_GET_INVOKER \
75
  BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
76
#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
77
78
#ifndef BOOST_NO_VOID_RETURNS
79
#  define BOOST_FUNCTION_VOID_RETURN_TYPE void
80
#  define BOOST_FUNCTION_RETURN(X) X
81
#else
82
#  define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
83
#  define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
84
#endif
85
86
namespace boost {
87
  namespace detail {
88
    namespace function {
89
      template<
90
        typename FunctionPtr,
91
        typename R BOOST_FUNCTION_COMMA
92
        BOOST_FUNCTION_TEMPLATE_PARMS
93
        >
94
      struct BOOST_FUNCTION_FUNCTION_INVOKER
95
      {
96
        static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
97
                        BOOST_FUNCTION_PARMS)
98
        {
99
          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr);
100
          return f(BOOST_FUNCTION_ARGS);
101
        }
102
      };
103
104
      template<
105
        typename FunctionPtr,
106
        typename R BOOST_FUNCTION_COMMA
107
        BOOST_FUNCTION_TEMPLATE_PARMS
108
        >
109
      struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
110
      {
111
        static BOOST_FUNCTION_VOID_RETURN_TYPE
112
        invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
113
               BOOST_FUNCTION_PARMS)
114
115
        {
116
          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr);
117
          BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
118
        }
119
      };
120
121
      template<
122
        typename FunctionObj,
123
        typename R BOOST_FUNCTION_COMMA
124
        BOOST_FUNCTION_TEMPLATE_PARMS
125
      >
126
      struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
127
      {
128
        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
129
                        BOOST_FUNCTION_PARMS)
130
131
60
        {
132
60
          FunctionObj* f;
133
60
          if (function_allows_small_object_optimization<FunctionObj>::value)
134
0
            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
135
60
          else
136
60
            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
137
60
          return (*f)(BOOST_FUNCTION_ARGS);
138
60
        }
139
      };
140
141
      template<
142
        typename FunctionObj,
143
        typename R BOOST_FUNCTION_COMMA
144
        BOOST_FUNCTION_TEMPLATE_PARMS
145
      >
146
      struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
147
      {
148
        static BOOST_FUNCTION_VOID_RETURN_TYPE
149
        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
150
               BOOST_FUNCTION_PARMS)
151
152
        {
153
          FunctionObj* f;
154
          if (function_allows_small_object_optimization<FunctionObj>::value)
155
            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
156
          else
157
            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
158
          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
159
        }
160
      };
161
162
      template<
163
        typename FunctionObj,
164
        typename R BOOST_FUNCTION_COMMA
165
        BOOST_FUNCTION_TEMPLATE_PARMS
166
      >
167
      struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
168
      {
169
        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
170
                        BOOST_FUNCTION_PARMS)
171
172
        {
173
          FunctionObj* f =
174
            reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
175
          return (*f)(BOOST_FUNCTION_ARGS);
176
        }
177
      };
178
179
      template<
180
        typename FunctionObj,
181
        typename R BOOST_FUNCTION_COMMA
182
        BOOST_FUNCTION_TEMPLATE_PARMS
183
      >
184
      struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
185
      {
186
        static BOOST_FUNCTION_VOID_RETURN_TYPE
187
        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
188
               BOOST_FUNCTION_PARMS)
189
190
        {
191
          FunctionObj* f =
192
            reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
193
          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
194
        }
195
      };
196
197
#if BOOST_FUNCTION_NUM_ARGS > 0
198
      /* Handle invocation of member pointers. */
199
      template<
200
        typename MemberPtr,
201
        typename R BOOST_FUNCTION_COMMA
202
        BOOST_FUNCTION_TEMPLATE_PARMS
203
      >
204
      struct BOOST_FUNCTION_MEMBER_INVOKER
205
      {
206
        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
207
                        BOOST_FUNCTION_PARMS)
208
209
        {
210
          MemberPtr* f =
211
            reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
212
          return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
213
        }
214
      };
215
216
      template<
217
        typename MemberPtr,
218
        typename R BOOST_FUNCTION_COMMA
219
        BOOST_FUNCTION_TEMPLATE_PARMS
220
      >
221
      struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
222
      {
223
        static BOOST_FUNCTION_VOID_RETURN_TYPE
224
        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
225
               BOOST_FUNCTION_PARMS)
226
227
        {
228
          MemberPtr* f =
229
            reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
230
          BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
231
        }
232
      };
233
#endif
234
235
      template<
236
        typename FunctionPtr,
237
        typename R BOOST_FUNCTION_COMMA
238
        BOOST_FUNCTION_TEMPLATE_PARMS
239
      >
240
      struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
241
      {
242
        typedef typename conditional<(is_void<R>::value),
243
                            BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
244
                            FunctionPtr,
245
                            R BOOST_FUNCTION_COMMA
246
                            BOOST_FUNCTION_TEMPLATE_ARGS
247
                          >,
248
                          BOOST_FUNCTION_FUNCTION_INVOKER<
249
                            FunctionPtr,
250
                            R BOOST_FUNCTION_COMMA
251
                            BOOST_FUNCTION_TEMPLATE_ARGS
252
                          >
253
                       >::type type;
254
      };
255
256
      template<
257
        typename FunctionObj,
258
        typename R BOOST_FUNCTION_COMMA
259
        BOOST_FUNCTION_TEMPLATE_PARMS
260
       >
261
      struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
262
      {
263
        typedef typename conditional<(is_void<R>::value),
264
                            BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
265
                            FunctionObj,
266
                            R BOOST_FUNCTION_COMMA
267
                            BOOST_FUNCTION_TEMPLATE_ARGS
268
                          >,
269
                          BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
270
                            FunctionObj,
271
                            R BOOST_FUNCTION_COMMA
272
                            BOOST_FUNCTION_TEMPLATE_ARGS
273
                          >
274
                       >::type type;
275
      };
276
277
      template<
278
        typename FunctionObj,
279
        typename R BOOST_FUNCTION_COMMA
280
        BOOST_FUNCTION_TEMPLATE_PARMS
281
       >
282
      struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
283
      {
284
        typedef typename conditional<(is_void<R>::value),
285
                            BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
286
                            FunctionObj,
287
                            R BOOST_FUNCTION_COMMA
288
                            BOOST_FUNCTION_TEMPLATE_ARGS
289
                          >,
290
                          BOOST_FUNCTION_FUNCTION_REF_INVOKER<
291
                            FunctionObj,
292
                            R BOOST_FUNCTION_COMMA
293
                            BOOST_FUNCTION_TEMPLATE_ARGS
294
                          >
295
                       >::type type;
296
      };
297
298
#if BOOST_FUNCTION_NUM_ARGS > 0
299
      /* Retrieve the appropriate invoker for a member pointer.  */
300
      template<
301
        typename MemberPtr,
302
        typename R BOOST_FUNCTION_COMMA
303
        BOOST_FUNCTION_TEMPLATE_PARMS
304
       >
305
      struct BOOST_FUNCTION_GET_MEMBER_INVOKER
306
      {
307
        typedef typename conditional<(is_void<R>::value),
308
                            BOOST_FUNCTION_VOID_MEMBER_INVOKER<
309
                            MemberPtr,
310
                            R BOOST_FUNCTION_COMMA
311
                            BOOST_FUNCTION_TEMPLATE_ARGS
312
                          >,
313
                          BOOST_FUNCTION_MEMBER_INVOKER<
314
                            MemberPtr,
315
                            R BOOST_FUNCTION_COMMA
316
                            BOOST_FUNCTION_TEMPLATE_ARGS
317
                          >
318
                       >::type type;
319
      };
320
#endif
321
322
      /* Given the tag returned by get_function_tag, retrieve the
323
         actual invoker that will be used for the given function
324
         object.
325
326
         Each specialization contains an "apply" nested class template
327
         that accepts the function object, return type, function
328
         argument types, and allocator. The resulting "apply" class
329
         contains two typedefs, "invoker_type" and "manager_type",
330
         which correspond to the invoker and manager types. */
331
      template<typename Tag>
332
      struct BOOST_FUNCTION_GET_INVOKER { };
333
334
      /* Retrieve the invoker for a function pointer. */
335
      template<>
336
      struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
337
      {
338
        template<typename FunctionPtr,
339
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
340
        struct apply
341
        {
342
          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
343
                             FunctionPtr,
344
                             R BOOST_FUNCTION_COMMA
345
                             BOOST_FUNCTION_TEMPLATE_ARGS
346
                           >::type
347
            invoker_type;
348
349
          typedef functor_manager<FunctionPtr> manager_type;
350
        };
351
352
        template<typename FunctionPtr, typename Allocator,
353
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
354
        struct apply_a
355
        {
356
          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
357
                             FunctionPtr,
358
                             R BOOST_FUNCTION_COMMA
359
                             BOOST_FUNCTION_TEMPLATE_ARGS
360
                           >::type
361
            invoker_type;
362
363
          typedef functor_manager<FunctionPtr> manager_type;
364
        };
365
      };
366
367
#if BOOST_FUNCTION_NUM_ARGS > 0
368
      /* Retrieve the invoker for a member pointer. */
369
      template<>
370
      struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
371
      {
372
        template<typename MemberPtr,
373
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
374
        struct apply
375
        {
376
          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
377
                             MemberPtr,
378
                             R BOOST_FUNCTION_COMMA
379
                             BOOST_FUNCTION_TEMPLATE_ARGS
380
                           >::type
381
            invoker_type;
382
383
          typedef functor_manager<MemberPtr> manager_type;
384
        };
385
386
        template<typename MemberPtr, typename Allocator,
387
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
388
        struct apply_a
389
        {
390
          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
391
                             MemberPtr,
392
                             R BOOST_FUNCTION_COMMA
393
                             BOOST_FUNCTION_TEMPLATE_ARGS
394
                           >::type
395
            invoker_type;
396
397
          typedef functor_manager<MemberPtr> manager_type;
398
        };
399
      };
400
#endif
401
402
      /* Retrieve the invoker for a function object. */
403
      template<>
404
      struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
405
      {
406
        template<typename FunctionObj,
407
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
408
        struct apply
409
        {
410
          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
411
                             FunctionObj,
412
                             R BOOST_FUNCTION_COMMA
413
                             BOOST_FUNCTION_TEMPLATE_ARGS
414
                           >::type
415
            invoker_type;
416
417
          typedef functor_manager<FunctionObj> manager_type;
418
        };
419
420
        template<typename FunctionObj, typename Allocator,
421
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
422
        struct apply_a
423
        {
424
          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
425
                             FunctionObj,
426
                             R BOOST_FUNCTION_COMMA
427
                             BOOST_FUNCTION_TEMPLATE_ARGS
428
                           >::type
429
            invoker_type;
430
431
          typedef functor_manager_a<FunctionObj, Allocator> manager_type;
432
        };
433
      };
434
435
      /* Retrieve the invoker for a reference to a function object. */
436
      template<>
437
      struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
438
      {
439
        template<typename RefWrapper,
440
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
441
        struct apply
442
        {
443
          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
444
                             typename RefWrapper::type,
445
                             R BOOST_FUNCTION_COMMA
446
                             BOOST_FUNCTION_TEMPLATE_ARGS
447
                           >::type
448
            invoker_type;
449
450
          typedef reference_manager<typename RefWrapper::type> manager_type;
451
        };
452
453
        template<typename RefWrapper, typename Allocator,
454
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
455
        struct apply_a
456
        {
457
          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
458
                             typename RefWrapper::type,
459
                             R BOOST_FUNCTION_COMMA
460
                             BOOST_FUNCTION_TEMPLATE_ARGS
461
                           >::type
462
            invoker_type;
463
464
          typedef reference_manager<typename RefWrapper::type> manager_type;
465
        };
466
      };
467
468
469
      /**
470
       * vtable for a specific boost::function instance. This
471
       * structure must be an aggregate so that we can use static
472
       * initialization in boost::function's assign_to and assign_to_a
473
       * members. It therefore cannot have any constructors,
474
       * destructors, base classes, etc.
475
       */
476
      template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
477
      struct BOOST_FUNCTION_VTABLE
478
      {
479
#ifndef BOOST_NO_VOID_RETURNS
480
        typedef R         result_type;
481
#else
482
        typedef typename function_return_type<R>::type result_type;
483
#endif // BOOST_NO_VOID_RETURNS
484
485
        typedef result_type (*invoker_type)(function_buffer&
486
                                            BOOST_FUNCTION_COMMA
487
                                            BOOST_FUNCTION_TEMPLATE_ARGS);
488
489
        template<typename F>
490
        bool assign_to(F f, function_buffer& functor) const
491
6
        {
492
6
          typedef typename get_function_tag<F>::type tag;
493
6
          return assign_to(f, functor, tag());
494
6
        }
495
        template<typename F,typename Allocator>
496
        bool assign_to_a(F f, function_buffer& functor, Allocator a) const
497
        {
498
          typedef typename get_function_tag<F>::type tag;
499
          return assign_to_a(f, functor, a, tag());
500
        }
501
502
        void clear(function_buffer& functor) const
503
18
        {
504
18
          if (base.manager)
505
18
            base.manager(functor, functor, destroy_functor_tag);
506
18
        }
507
508
      private:
509
        // Function pointers
510
        template<typename FunctionPtr>
511
        bool
512
        assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const
513
        {
514
          this->clear(functor);
515
          if (f) {
516
            // should be a reinterpret cast, but some compilers insist
517
            // on giving cv-qualifiers to free functions
518
            functor.members.func_ptr = reinterpret_cast<void (*)()>(f);
519
            return true;
520
          } else {
521
            return false;
522
          }
523
        }
524
        template<typename FunctionPtr,typename Allocator>
525
        bool
526
        assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const
527
        {
528
          return assign_to(f,functor,function_ptr_tag());
529
        }
530
531
        // Member pointers
532
#if BOOST_FUNCTION_NUM_ARGS > 0
533
        template<typename MemberPtr>
534
        bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const
535
        {
536
          // DPG TBD: Add explicit support for member function
537
          // objects, so we invoke through mem_fn() but we retain the
538
          // right target_type() values.
539
          if (f) {
540
            this->assign_to(boost::mem_fn(f), functor);
541
            return true;
542
          } else {
543
            return false;
544
          }
545
        }
546
        template<typename MemberPtr,typename Allocator>
547
        bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const
548
        {
549
          // DPG TBD: Add explicit support for member function
550
          // objects, so we invoke through mem_fn() but we retain the
551
          // right target_type() values.
552
          if (f) {
553
            this->assign_to_a(boost::mem_fn(f), functor, a);
554
            return true;
555
          } else {
556
            return false;
557
          }
558
        }
559
#endif // BOOST_FUNCTION_NUM_ARGS > 0
560
561
        // Function objects
562
        // Assign to a function object using the small object optimization
563
        template<typename FunctionObj>
564
        void
565
        assign_functor(FunctionObj f, function_buffer& functor, true_type) const
566
        {
567
          new (reinterpret_cast<void*>(functor.data)) FunctionObj(f);
568
        }
569
        template<typename FunctionObj,typename Allocator>
570
        void
571
        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, true_type) const
572
        {
573
          assign_functor(f,functor,true_type());
574
        }
575
576
        // Assign to a function object allocated on the heap.
577
        template<typename FunctionObj>
578
        void
579
        assign_functor(FunctionObj f, function_buffer& functor, false_type) const
580
6
        {
581
6
          functor.members.obj_ptr = new FunctionObj(f);
582
6
        }
583
        template<typename FunctionObj,typename Allocator>
584
        void
585
        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, false_type) const
586
        {
587
          typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
588
#if defined(BOOST_NO_CXX11_ALLOCATOR)
589
          typedef typename Allocator::template rebind<functor_wrapper_type>::other
590
            wrapper_allocator_type;
591
          typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
592
#else
593
          using wrapper_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<functor_wrapper_type>;
594
          using wrapper_allocator_pointer_type = typename std::allocator_traits<wrapper_allocator_type>::pointer;
595
#endif
596
          wrapper_allocator_type wrapper_allocator(a);
597
          wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
598
#if defined(BOOST_NO_CXX11_ALLOCATOR)
599
          wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
600
#else
601
          std::allocator_traits<wrapper_allocator_type>::construct(wrapper_allocator, copy, functor_wrapper_type(f,a));
602
#endif
603
          functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
604
          functor.members.obj_ptr = new_f;
605
        }
606
607
        template<typename FunctionObj>
608
        bool
609
        assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
610
6
        {
611
6
          if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
612
6
            assign_functor(f, functor,
613
6
                           integral_constant<bool, (function_allows_small_object_optimization<FunctionObj>::value)>());
614
6
            return true;
615
6
          } else {
616
0
            return false;
617
0
          }
618
6
        }
619
        template<typename FunctionObj,typename Allocator>
620
        bool
621
        assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const
622
        {
623
          if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
624
            assign_functor_a(f, functor, a,
625
                           integral_constant<bool, (function_allows_small_object_optimization<FunctionObj>::value)>());
626
            return true;
627
          } else {
628
            return false;
629
          }
630
        }
631
632
        // Reference to a function object
633
        template<typename FunctionObj>
634
        bool
635
        assign_to(const reference_wrapper<FunctionObj>& f,
636
                  function_buffer& functor, function_obj_ref_tag) const
637
        {
638
          functor.members.obj_ref.obj_ptr = (void *)(f.get_pointer());
639
          functor.members.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
640
          functor.members.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
641
          return true;
642
        }
643
        template<typename FunctionObj,typename Allocator>
644
        bool
645
        assign_to_a(const reference_wrapper<FunctionObj>& f,
646
                  function_buffer& functor, Allocator, function_obj_ref_tag) const
647
        {
648
          return assign_to(f,functor,function_obj_ref_tag());
649
        }
650
651
      public:
652
        vtable_base base;
653
        invoker_type invoker;
654
      };
655
    } // end namespace function
656
  } // end namespace detail
657
658
  template<
659
    typename R BOOST_FUNCTION_COMMA
660
    BOOST_FUNCTION_TEMPLATE_PARMS
661
  >
662
  class BOOST_FUNCTION_FUNCTION : public function_base
663
  {
664
  public:
665
#ifndef BOOST_NO_VOID_RETURNS
666
    typedef R         result_type;
667
#else
668
    typedef  typename boost::detail::function::function_return_type<R>::type
669
      result_type;
670
#endif // BOOST_NO_VOID_RETURNS
671
672
  private:
673
    typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
674
              R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
675
      vtable_type;
676
677
90
    vtable_type* get_vtable() const {
678
90
      return reinterpret_cast<vtable_type*>(
679
90
               reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
680
90
    }
681
682
    struct clear_type {};
683
684
  public:
685
    BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
686
687
    // add signature for boost::lambda
688
    template<typename Args>
689
    struct sig
690
    {
691
      typedef result_type type;
692
    };
693
694
#if BOOST_FUNCTION_NUM_ARGS == 1
695
    typedef T0 argument_type;
696
#elif BOOST_FUNCTION_NUM_ARGS == 2
697
    typedef T0 first_argument_type;
698
    typedef T1 second_argument_type;
699
#endif
700
701
    BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
702
    BOOST_FUNCTION_ARG_TYPES
703
704
    typedef BOOST_FUNCTION_FUNCTION self_type;
705
706
    BOOST_DEFAULTED_FUNCTION(BOOST_FUNCTION_FUNCTION(), : function_base() {})
707
708
    // MSVC chokes if the following two constructors are collapsed into
709
    // one with a default parameter.
710
    template<typename Functor>
711
    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
712
#ifndef BOOST_NO_SFINAE
713
                            ,typename boost::enable_if_<
714
                             !(is_integral<Functor>::value),
715
                                        int>::type = 0
716
#endif // BOOST_NO_SFINAE
717
                            ) :
718
      function_base()
719
6
    {
720
6
      this->assign_to(f);
721
6
    }
722
    template<typename Functor,typename Allocator>
723
    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
724
#ifndef BOOST_NO_SFINAE
725
                            ,typename boost::enable_if_<
726
                              !(is_integral<Functor>::value),
727
                                        int>::type = 0
728
#endif // BOOST_NO_SFINAE
729
                            ) :
730
      function_base()
731
    {
732
      this->assign_to_a(f,a);
733
    }
734
735
#ifndef BOOST_NO_SFINAE
736
    BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
737
#else
738
    BOOST_FUNCTION_FUNCTION(int zero) : function_base()
739
    {
740
      BOOST_ASSERT(zero == 0);
741
    }
742
#endif
743
744
    BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
745
24
    {
746
24
      this->assign_to_own(f);
747
24
    }
748
749
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
750
    BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
751
    {
752
      this->move_assign(f);
753
    }
754
#endif
755
756
36
    ~BOOST_FUNCTION_FUNCTION() { clear(); }
757
758
    result_type operator()(BOOST_FUNCTION_PARMS) const
759
60
    {
760
60
      if (this->empty())
761
0
        boost::throw_exception(bad_function_call());
762
763
60
      return get_vtable()->invoker
764
60
               (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
765
60
    }
766
767
    // The distinction between when to use BOOST_FUNCTION_FUNCTION and
768
    // when to use self_type is obnoxious. MSVC cannot handle self_type as
769
    // the return type of these assignment operators, but Borland C++ cannot
770
    // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
771
    // construct.
772
    template<typename Functor>
773
#ifndef BOOST_NO_SFINAE
774
    typename boost::enable_if_<
775
                  !(is_integral<Functor>::value),
776
               BOOST_FUNCTION_FUNCTION&>::type
777
#else
778
    BOOST_FUNCTION_FUNCTION&
779
#endif
780
    operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
781
    {
782
      this->clear();
783
      BOOST_TRY  {
784
        this->assign_to(f);
785
      } BOOST_CATCH (...) {
786
        vtable = 0;
787
        BOOST_RETHROW;
788
      }
789
      BOOST_CATCH_END
790
      return *this;
791
    }
792
    template<typename Functor,typename Allocator>
793
    void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
794
    {
795
      this->clear();
796
      BOOST_TRY{
797
        this->assign_to_a(f,a);
798
      } BOOST_CATCH (...) {
799
        vtable = 0;
800
        BOOST_RETHROW;
801
      }
802
      BOOST_CATCH_END
803
    }
804
805
#ifndef BOOST_NO_SFINAE
806
    BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
807
    {
808
      this->clear();
809
      return *this;
810
    }
811
#else
812
    BOOST_FUNCTION_FUNCTION& operator=(int zero)
813
    {
814
      BOOST_ASSERT(zero == 0);
815
      this->clear();
816
      return *this;
817
    }
818
#endif
819
820
    // Assignment from another BOOST_FUNCTION_FUNCTION
821
    BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
822
    {
823
      if (&f == this)
824
        return *this;
825
826
      this->clear();
827
      BOOST_TRY {
828
        this->assign_to_own(f);
829
      } BOOST_CATCH (...) {
830
        vtable = 0;
831
        BOOST_RETHROW;
832
      }
833
      BOOST_CATCH_END
834
      return *this;
835
    }
836
837
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
838
    // Move assignment from another BOOST_FUNCTION_FUNCTION
839
    BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
840
    {
841
      if (&f == this)
842
        return *this;
843
844
      this->clear();
845
      BOOST_TRY {
846
        this->move_assign(f);
847
      } BOOST_CATCH (...) {
848
        vtable = 0;
849
        BOOST_RETHROW;
850
      }
851
      BOOST_CATCH_END
852
      return *this;
853
    }
854
#endif
855
856
    void swap(BOOST_FUNCTION_FUNCTION& other)
857
    {
858
      if (&other == this)
859
        return;
860
861
      BOOST_FUNCTION_FUNCTION tmp;
862
      tmp.move_assign(*this);
863
      this->move_assign(other);
864
      other.move_assign(tmp);
865
    }
866
867
    // Clear out a target, if there is one
868
    void clear()
869
36
    {
870
36
      if (vtable) {
871
18
        if (!this->has_trivial_copy_and_destroy())
872
18
          get_vtable()->clear(this->functor);
873
18
        vtable = 0;
874
18
      }
875
36
    }
876
877
#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
878
    // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
879
    operator bool () const { return !this->empty(); }
880
#else
881
  private:
882
    struct dummy {
883
      void nonnull() {}
884
    };
885
886
    typedef void (dummy::*safe_bool)();
887
888
  public:
889
    operator safe_bool () const
890
      { return (this->empty())? 0 : &dummy::nonnull; }
891
892
    bool operator!() const
893
      { return this->empty(); }
894
#endif
895
896
  private:
897
    void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
898
24
    {
899
24
      if (!f.empty()) {
900
12
        this->vtable = f.vtable;
901
12
        if (this->has_trivial_copy_and_destroy()) {
902
          // Don't operate on storage directly since union type doesn't relax
903
          // strict aliasing rules, despite of having member char type.
904
#         if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
905
#           pragma GCC diagnostic push
906
            // This warning is technically correct, but we don't want to pay the price for initializing
907
            // just to silence a warning: https://github.com/boostorg/function/issues/27
908
#           pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
909
#         endif
910
0
          std::memcpy(this->functor.data, f.functor.data, sizeof(boost::detail::function::function_buffer));
911
#         if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
912
#           pragma GCC diagnostic pop
913
#         endif
914
0
        } else
915
12
          get_vtable()->base.manager(f.functor, this->functor,
916
12
                                     boost::detail::function::clone_functor_tag);
917
12
      }
918
24
    }
919
920
    template<typename Functor>
921
    void assign_to(Functor f)
922
6
    {
923
6
      using boost::detail::function::vtable_base;
924
925
6
      typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
926
6
      typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
927
6
      typedef typename get_invoker::
928
6
                         template apply<Functor, R BOOST_FUNCTION_COMMA
929
6
                        BOOST_FUNCTION_TEMPLATE_ARGS>
930
6
        handler_type;
931
932
6
      typedef typename handler_type::invoker_type invoker_type;
933
6
      typedef typename handler_type::manager_type manager_type;
934
935
      // Note: it is extremely important that this initialization use
936
      // static initialization. Otherwise, we will have a race
937
      // condition here in multi-threaded code. See
938
      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
939
6
      static const vtable_type stored_vtable =
940
6
        { { &manager_type::manage }, &invoker_type::invoke };
941
942
6
      if (stored_vtable.assign_to(f, functor)) {
943
6
        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
944
        // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
945
6
        if (boost::has_trivial_copy_constructor<Functor>::value &&
946
6
            boost::has_trivial_destructor<Functor>::value &&
947
6
            boost::detail::function::function_allows_small_object_optimization<Functor>::value)
948
0
          value |= static_cast<std::size_t>(0x01);
949
6
        vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
950
6
      } else
951
0
        vtable = 0;
952
6
    }
953
954
    template<typename Functor,typename Allocator>
955
    void assign_to_a(Functor f,Allocator a)
956
    {
957
      using boost::detail::function::vtable_base;
958
959
      typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
960
      typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
961
      typedef typename get_invoker::
962
                         template apply_a<Functor, Allocator, R BOOST_FUNCTION_COMMA
963
                         BOOST_FUNCTION_TEMPLATE_ARGS>
964
        handler_type;
965
966
      typedef typename handler_type::invoker_type invoker_type;
967
      typedef typename handler_type::manager_type manager_type;
968
969
      // Note: it is extremely important that this initialization use
970
      // static initialization. Otherwise, we will have a race
971
      // condition here in multi-threaded code. See
972
      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
973
      static const vtable_type stored_vtable =
974
        { { &manager_type::manage }, &invoker_type::invoke };
975
976
      if (stored_vtable.assign_to_a(f, functor, a)) {
977
        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
978
        // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
979
        if (boost::has_trivial_copy_constructor<Functor>::value &&
980
            boost::has_trivial_destructor<Functor>::value &&
981
            boost::detail::function::function_allows_small_object_optimization<Functor>::value)
982
          value |= static_cast<std::size_t>(0x01);
983
        vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
984
      } else
985
        vtable = 0;
986
    }
987
988
    // Moves the value from the specified argument to *this. If the argument
989
    // has its function object allocated on the heap, move_assign will pass
990
    // its buffer to *this, and set the argument's buffer pointer to NULL.
991
    void move_assign(BOOST_FUNCTION_FUNCTION& f)
992
    {
993
      if (&f == this)
994
        return;
995
996
      BOOST_TRY {
997
        if (!f.empty()) {
998
          this->vtable = f.vtable;
999
          if (this->has_trivial_copy_and_destroy()) {
1000
            // Don't operate on storage directly since union type doesn't relax
1001
            // strict aliasing rules, despite of having member char type.
1002
#           if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
1003
#             pragma GCC diagnostic push
1004
              // This warning is technically correct, but we don't want to pay the price for initializing
1005
              // just to silence a warning: https://github.com/boostorg/function/issues/27
1006
#             pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1007
#           endif
1008
            std::memcpy(this->functor.data, f.functor.data, sizeof(this->functor.data));
1009
#           if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
1010
#             pragma GCC diagnostic pop
1011
#           endif
1012
          } else
1013
            get_vtable()->base.manager(f.functor, this->functor,
1014
                                     boost::detail::function::move_functor_tag);
1015
          f.vtable = 0;
1016
        } else {
1017
          clear();
1018
        }
1019
      } BOOST_CATCH (...) {
1020
        vtable = 0;
1021
        BOOST_RETHROW;
1022
      }
1023
      BOOST_CATCH_END
1024
    }
1025
  };
1026
1027
  template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1028
  inline void swap(BOOST_FUNCTION_FUNCTION<
1029
                     R BOOST_FUNCTION_COMMA
1030
                     BOOST_FUNCTION_TEMPLATE_ARGS
1031
                   >& f1,
1032
                   BOOST_FUNCTION_FUNCTION<
1033
                     R BOOST_FUNCTION_COMMA
1034
                     BOOST_FUNCTION_TEMPLATE_ARGS
1035
                   >& f2)
1036
  {
1037
    f1.swap(f2);
1038
  }
1039
1040
// Poison comparisons between boost::function objects of the same type.
1041
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1042
  void operator==(const BOOST_FUNCTION_FUNCTION<
1043
                          R BOOST_FUNCTION_COMMA
1044
                          BOOST_FUNCTION_TEMPLATE_ARGS>&,
1045
                  const BOOST_FUNCTION_FUNCTION<
1046
                          R BOOST_FUNCTION_COMMA
1047
                          BOOST_FUNCTION_TEMPLATE_ARGS>&);
1048
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1049
  void operator!=(const BOOST_FUNCTION_FUNCTION<
1050
                          R BOOST_FUNCTION_COMMA
1051
                          BOOST_FUNCTION_TEMPLATE_ARGS>&,
1052
                  const BOOST_FUNCTION_FUNCTION<
1053
                          R BOOST_FUNCTION_COMMA
1054
                          BOOST_FUNCTION_TEMPLATE_ARGS>& );
1055
1056
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
1057
1058
#if BOOST_FUNCTION_NUM_ARGS == 0
1059
#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
1060
#else
1061
#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_FUNCTION_TEMPLATE_ARGS)
1062
#endif
1063
1064
template<typename R BOOST_FUNCTION_COMMA
1065
         BOOST_FUNCTION_TEMPLATE_PARMS>
1066
class function<BOOST_FUNCTION_PARTIAL_SPEC>
1067
  : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
1068
{
1069
  typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
1070
  typedef function self_type;
1071
1072
  struct clear_type {};
1073
1074
public:
1075
1076
  BOOST_DEFAULTED_FUNCTION(function(), : base_type() {})
1077
1078
  template<typename Functor>
1079
  function(Functor f
1080
#ifndef BOOST_NO_SFINAE
1081
           ,typename boost::enable_if_<
1082
                          !(is_integral<Functor>::value),
1083
                       int>::type = 0
1084
#endif
1085
           ) :
1086
    base_type(f)
1087
  {
1088
  }
1089
  template<typename Functor,typename Allocator>
1090
  function(Functor f, Allocator a
1091
#ifndef BOOST_NO_SFINAE
1092
           ,typename boost::enable_if_<
1093
                           !(is_integral<Functor>::value),
1094
                       int>::type = 0
1095
#endif
1096
           ) :
1097
    base_type(f,a)
1098
  {
1099
  }
1100
1101
#ifndef BOOST_NO_SFINAE
1102
  function(clear_type*) : base_type() {}
1103
#endif
1104
1105
  function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1106
1107
  function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
1108
1109
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1110
  // Move constructors
1111
  function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
1112
  function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
1113
#endif
1114
1115
  self_type& operator=(const self_type& f)
1116
  {
1117
    self_type(f).swap(*this);
1118
    return *this;
1119
  }
1120
1121
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1122
  self_type& operator=(self_type&& f)
1123
  {
1124
    self_type(static_cast<self_type&&>(f)).swap(*this);
1125
    return *this;
1126
  }
1127
#endif
1128
1129
  template<typename Functor>
1130
#ifndef BOOST_NO_SFINAE
1131
  typename boost::enable_if_<
1132
                         !(is_integral<Functor>::value),
1133
                      self_type&>::type
1134
#else
1135
  self_type&
1136
#endif
1137
  operator=(Functor f)
1138
  {
1139
    self_type(f).swap(*this);
1140
    return *this;
1141
  }
1142
1143
#ifndef BOOST_NO_SFINAE
1144
  self_type& operator=(clear_type*)
1145
  {
1146
    this->clear();
1147
    return *this;
1148
  }
1149
#endif
1150
1151
  self_type& operator=(const base_type& f)
1152
  {
1153
    self_type(f).swap(*this);
1154
    return *this;
1155
  }
1156
1157
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1158
  self_type& operator=(base_type&& f)
1159
  {
1160
    self_type(static_cast<base_type&&>(f)).swap(*this);
1161
    return *this;
1162
  }
1163
#endif
1164
};
1165
1166
#undef BOOST_FUNCTION_PARTIAL_SPEC
1167
#endif // have partial specialization
1168
1169
} // end namespace boost
1170
1171
// Cleanup after ourselves...
1172
#undef BOOST_FUNCTION_VTABLE
1173
#undef BOOST_FUNCTION_COMMA
1174
#undef BOOST_FUNCTION_FUNCTION
1175
#undef BOOST_FUNCTION_FUNCTION_INVOKER
1176
#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
1177
#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1178
#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1179
#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
1180
#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1181
#undef BOOST_FUNCTION_MEMBER_INVOKER
1182
#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
1183
#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
1184
#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1185
#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1186
#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
1187
#undef BOOST_FUNCTION_GET_INVOKER
1188
#undef BOOST_FUNCTION_TEMPLATE_PARMS
1189
#undef BOOST_FUNCTION_TEMPLATE_ARGS
1190
#undef BOOST_FUNCTION_PARMS
1191
#undef BOOST_FUNCTION_PARM
1192
#ifdef BOOST_FUNCTION_ARG
1193
#   undef BOOST_FUNCTION_ARG
1194
#endif
1195
#undef BOOST_FUNCTION_ARGS
1196
#undef BOOST_FUNCTION_ARG_TYPE
1197
#undef BOOST_FUNCTION_ARG_TYPES
1198
#undef BOOST_FUNCTION_VOID_RETURN_TYPE
1199
#undef BOOST_FUNCTION_RETURN
1200
1201
#if defined(BOOST_MSVC)
1202
#   pragma warning( pop )
1203
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/iterator/detail/facade_iterator_category.hpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright David Abrahams 2003. Use, modification and distribution is
2
// subject to the Boost Software License, Version 1.0. (See accompanying
3
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
5
# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
6
7
# include <boost/core/use_default.hpp>
8
9
# include <boost/iterator/iterator_categories.hpp>
10
11
# include <boost/mpl/or.hpp>  // used in iterator_tag inheritance logic
12
# include <boost/mpl/and.hpp>
13
# include <boost/mpl/if.hpp>
14
# include <boost/mpl/eval_if.hpp>
15
# include <boost/mpl/identity.hpp>
16
# include <boost/mpl/assert.hpp>
17
18
# include <boost/type_traits/is_same.hpp>
19
# include <boost/type_traits/is_const.hpp>
20
# include <boost/type_traits/is_reference.hpp>
21
# include <boost/type_traits/is_convertible.hpp>
22
23
# include <boost/type_traits/is_same.hpp>
24
25
# include <boost/iterator/detail/config_def.hpp> // try to keep this last
26
27
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
28
#  include <boost/detail/indirect_traits.hpp>
29
# endif
30
31
//
32
// iterator_category deduction for iterator_facade
33
//
34
35
namespace boost {
36
namespace iterators {
37
38
using boost::use_default;
39
40
namespace detail {
41
42
struct input_output_iterator_tag
43
  : std::input_iterator_tag
44
{
45
    // Using inheritance for only input_iterator_tag helps to avoid
46
    // ambiguities when a stdlib implementation dispatches on a
47
    // function which is overloaded on both input_iterator_tag and
48
    // output_iterator_tag, as STLPort does, in its __valid_range
49
    // function.  I claim it's better to avoid the ambiguity in these
50
    // cases.
51
    operator std::output_iterator_tag() const
52
0
    {
53
0
        return std::output_iterator_tag();
54
0
    }
55
};
56
57
//
58
// True iff the user has explicitly disabled writability of this
59
// iterator.  Pass the iterator_facade's Value parameter and its
60
// nested ::reference type.
61
//
62
template <class ValueParam, class Reference>
63
struct iterator_writability_disabled
64
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
65
  : mpl::or_<
66
        is_const<Reference>
67
      , boost::detail::indirect_traits::is_reference_to_const<Reference>
68
      , is_const<ValueParam>
69
    >
70
# else
71
  : is_const<ValueParam>
72
# endif
73
{};
74
75
76
//
77
// Convert an iterator_facade's traversal category, Value parameter,
78
// and ::reference type to an appropriate old-style category.
79
//
80
// Due to changeset 21683, this now never results in a category convertible
81
// to output_iterator_tag.
82
//
83
// Change at: https://svn.boost.org/trac/boost/changeset/21683
84
template <class Traversal, class ValueParam, class Reference>
85
struct iterator_facade_default_category
86
  : mpl::eval_if<
87
        mpl::and_<
88
            is_reference<Reference>
89
          , is_convertible<Traversal,forward_traversal_tag>
90
        >
91
      , mpl::eval_if<
92
            is_convertible<Traversal,random_access_traversal_tag>
93
          , mpl::identity<std::random_access_iterator_tag>
94
          , mpl::if_<
95
                is_convertible<Traversal,bidirectional_traversal_tag>
96
              , std::bidirectional_iterator_tag
97
              , std::forward_iterator_tag
98
            >
99
        >
100
      , typename mpl::eval_if<
101
            mpl::and_<
102
                is_convertible<Traversal, single_pass_traversal_tag>
103
104
                // check for readability
105
              , is_convertible<Reference, ValueParam>
106
            >
107
          , mpl::identity<std::input_iterator_tag>
108
          , mpl::identity<Traversal>
109
        >
110
    >
111
{
112
};
113
114
// True iff T is convertible to an old-style iterator category.
115
template <class T>
116
struct is_iterator_category
117
  : mpl::or_<
118
        is_convertible<T,std::input_iterator_tag>
119
      , is_convertible<T,std::output_iterator_tag>
120
    >
121
{
122
};
123
124
template <class T>
125
struct is_iterator_traversal
126
  : is_convertible<T,incrementable_traversal_tag>
127
{};
128
129
//
130
// A composite iterator_category tag convertible to Category (a pure
131
// old-style category) and Traversal (a pure traversal tag).
132
// Traversal must be a strict increase of the traversal power given by
133
// Category.
134
//
135
template <class Category, class Traversal>
136
struct iterator_category_with_traversal
137
  : Category, Traversal
138
{
139
    // Make sure this isn't used to build any categories where
140
    // convertibility to Traversal is redundant.  Should just use the
141
    // Category element in that case.
142
    BOOST_MPL_ASSERT_NOT((
143
        is_convertible<
144
              typename iterator_category_to_traversal<Category>::type
145
            , Traversal
146
          >));
147
148
    BOOST_MPL_ASSERT((is_iterator_category<Category>));
149
    BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
150
    BOOST_MPL_ASSERT_NOT((is_iterator_traversal<Category>));
151
#  if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
152
    BOOST_MPL_ASSERT((is_iterator_traversal<Traversal>));
153
#  endif
154
};
155
156
// Computes an iterator_category tag whose traversal is Traversal and
157
// which is appropriate for an iterator
158
template <class Traversal, class ValueParam, class Reference>
159
struct facade_iterator_category_impl
160
{
161
    BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
162
163
    typedef typename iterator_facade_default_category<
164
        Traversal,ValueParam,Reference
165
    >::type category;
166
167
    typedef typename mpl::if_<
168
        is_same<
169
            Traversal
170
          , typename iterator_category_to_traversal<category>::type
171
        >
172
      , category
173
      , iterator_category_with_traversal<category,Traversal>
174
    >::type type;
175
};
176
177
//
178
// Compute an iterator_category for iterator_facade
179
//
180
template <class CategoryOrTraversal, class ValueParam, class Reference>
181
struct facade_iterator_category
182
  : mpl::eval_if<
183
        is_iterator_category<CategoryOrTraversal>
184
      , mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
185
      , facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
186
    >
187
{
188
};
189
190
}}} // namespace boost::iterators::detail
191
192
# include <boost/iterator/detail/config_undef.hpp>
193
194
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/iterator/distance.hpp
Line
Count
Source
1
// Copyright (C) 2017 Michel Morin.
2
//
3
// Distributed under the Boost Software License, Version 1.0.
4
// (See accompanying file LICENSE_1_0.txt or copy at
5
// http://www.boost.org/LICENSE_1_0.txt)
6
7
#ifndef BOOST_ITERATOR_DISTANCE_HPP
8
#define BOOST_ITERATOR_DISTANCE_HPP
9
10
#include <boost/config.hpp>
11
#include <boost/iterator/iterator_categories.hpp>
12
#include <boost/iterator/iterator_traits.hpp>
13
14
namespace boost {
15
namespace iterators {
16
17
    namespace detail {
18
        template <typename SinglePassIterator>
19
        inline BOOST_CXX14_CONSTEXPR typename iterator_difference<SinglePassIterator>::type
20
        distance_impl(
21
            SinglePassIterator first
22
          , SinglePassIterator last
23
          , single_pass_traversal_tag
24
        )
25
        {
26
            typename iterator_difference<SinglePassIterator>::type n = 0;
27
            while (first != last) {
28
                ++first;
29
                ++n;
30
            }
31
            return n;
32
        }
33
34
        template <typename RandomAccessIterator>
35
        inline BOOST_CXX14_CONSTEXPR typename iterator_difference<RandomAccessIterator>::type
36
        distance_impl(
37
            RandomAccessIterator first
38
          , RandomAccessIterator last
39
          , random_access_traversal_tag
40
        )
41
3
        {
42
3
            return last - first;
43
3
        }
44
    }
45
46
    namespace distance_adl_barrier {
47
        template <typename SinglePassIterator>
48
        inline BOOST_CXX14_CONSTEXPR typename iterator_difference<SinglePassIterator>::type
49
        distance(SinglePassIterator first, SinglePassIterator last)
50
3
        {
51
3
            return detail::distance_impl(
52
3
                first, last, typename iterator_traversal<SinglePassIterator>::type()
53
3
            );
54
3
        }
55
    }
56
57
    using namespace distance_adl_barrier;
58
59
} // namespace iterators
60
61
using namespace iterators::distance_adl_barrier;
62
63
} // namespace boost
64
65
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/iterator/iterator_adaptor.hpp
Line
Count
Source
1
// (C) Copyright David Abrahams 2002.
2
// (C) Copyright Jeremy Siek    2002.
3
// (C) Copyright Thomas Witt    2002.
4
// Distributed under the Boost Software License, Version 1.0. (See
5
// accompanying file LICENSE_1_0.txt or copy at
6
// http://www.boost.org/LICENSE_1_0.txt)
7
#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
8
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
9
10
#include <boost/static_assert.hpp>
11
12
#include <boost/core/use_default.hpp>
13
14
#include <boost/iterator/iterator_categories.hpp>
15
#include <boost/iterator/iterator_facade.hpp>
16
#include <boost/iterator/detail/enable_if.hpp>
17
18
#include <boost/mpl/and.hpp>
19
#include <boost/mpl/not.hpp>
20
#include <boost/mpl/or.hpp>
21
22
#include <boost/type_traits/is_same.hpp>
23
#include <boost/type_traits/is_convertible.hpp>
24
25
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
26
# include <boost/type_traits/remove_reference.hpp>
27
#endif
28
29
#include <boost/type_traits/add_reference.hpp>
30
#include <boost/iterator/detail/config_def.hpp>
31
32
#include <boost/iterator/iterator_traits.hpp>
33
34
namespace boost {
35
namespace iterators {
36
37
  // Used as a default template argument internally, merely to
38
  // indicate "use the default", this can also be passed by users
39
  // explicitly in order to specify that the default should be used.
40
  using boost::use_default;
41
42
} // namespace iterators
43
44
// the incompleteness of use_default causes massive problems for
45
// is_convertible (naturally).  This workaround is fortunately not
46
// needed for vc6/vc7.
47
template<class To>
48
struct is_convertible<use_default,To>
49
  : mpl::false_ {};
50
51
namespace iterators {
52
53
  namespace detail
54
  {
55
56
    //
57
    // Result type used in enable_if_convertible meta function.
58
    // This can be an incomplete type, as only pointers to
59
    // enable_if_convertible< ... >::type are used.
60
    // We could have used void for this, but conversion to
61
    // void* is just to easy.
62
    //
63
    struct enable_type;
64
  }
65
66
67
  //
68
  // enable_if for use in adapted iterators constructors.
69
  //
70
  // In order to provide interoperability between adapted constant and
71
  // mutable iterators, adapted iterators will usually provide templated
72
  // conversion constructors of the following form
73
  //
74
  // template <class BaseIterator>
75
  // class adapted_iterator :
76
  //   public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
77
  // {
78
  // public:
79
  //
80
  //   ...
81
  //
82
  //   template <class OtherIterator>
83
  //   adapted_iterator(
84
  //       OtherIterator const& it
85
  //     , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
86
  //
87
  //   ...
88
  // };
89
  //
90
  // enable_if_convertible is used to remove those overloads from the overload
91
  // set that cannot be instantiated. For all practical purposes only overloads
92
  // for constant/mutable interaction will remain. This has the advantage that
93
  // meta functions like boost::is_convertible do not return false positives,
94
  // as they can only look at the signature of the conversion constructor
95
  // and not at the actual instantiation.
96
  //
97
  // enable_if_interoperable can be safely used in user code. It falls back to
98
  // always enabled for compilers that don't support enable_if or is_convertible.
99
  // There is no need for compiler specific workarounds in user code.
100
  //
101
  // The operators implementation relies on boost::is_convertible not returning
102
  // false positives for user/library defined iterator types. See comments
103
  // on operator implementation for consequences.
104
  //
105
#  if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
106
107
  template <class From, class To>
108
  struct enable_if_convertible
109
  {
110
      typedef boost::iterators::detail::enable_type type;
111
  };
112
113
#  elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292))
114
115
  // For some reason vc7.1 needs us to "cut off" instantiation
116
  // of is_convertible in a few cases.
117
  template<typename From, typename To>
118
  struct enable_if_convertible
119
    : iterators::enable_if<
120
        mpl::or_<
121
            is_same<From,To>
122
          , is_convertible<From, To>
123
        >
124
      , boost::iterators::detail::enable_type
125
    >
126
  {};
127
128
#  else
129
130
  template<typename From, typename To>
131
  struct enable_if_convertible
132
    : iterators::enable_if<
133
          is_convertible<From, To>
134
        , boost::iterators::detail::enable_type
135
      >
136
  {};
137
138
# endif
139
140
  //
141
  // Default template argument handling for iterator_adaptor
142
  //
143
  namespace detail
144
  {
145
    // If T is use_default, return the result of invoking
146
    // DefaultNullaryFn, otherwise return T.
147
    template <class T, class DefaultNullaryFn>
148
    struct ia_dflt_help
149
      : mpl::eval_if<
150
            is_same<T, use_default>
151
          , DefaultNullaryFn
152
          , mpl::identity<T>
153
        >
154
    {
155
    };
156
157
    // A metafunction which computes an iterator_adaptor's base class,
158
    // a specialization of iterator_facade.
159
    template <
160
        class Derived
161
      , class Base
162
      , class Value
163
      , class Traversal
164
      , class Reference
165
      , class Difference
166
    >
167
    struct iterator_adaptor_base
168
    {
169
        typedef iterator_facade<
170
            Derived
171
172
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
173
          , typename boost::iterators::detail::ia_dflt_help<
174
                Value
175
              , mpl::eval_if<
176
                    is_same<Reference,use_default>
177
                  , iterator_value<Base>
178
                  , remove_reference<Reference>
179
                >
180
            >::type
181
# else
182
          , typename boost::iterators::detail::ia_dflt_help<
183
                Value, iterator_value<Base>
184
            >::type
185
# endif
186
187
          , typename boost::iterators::detail::ia_dflt_help<
188
                Traversal
189
              , iterator_traversal<Base>
190
            >::type
191
192
          , typename boost::iterators::detail::ia_dflt_help<
193
                Reference
194
              , mpl::eval_if<
195
                    is_same<Value,use_default>
196
                  , iterator_reference<Base>
197
                  , add_reference<Value>
198
                >
199
            >::type
200
201
          , typename boost::iterators::detail::ia_dflt_help<
202
                Difference, iterator_difference<Base>
203
            >::type
204
        >
205
        type;
206
    };
207
208
    // workaround for aC++ CR JAGaf33512
209
    template <class Tr1, class Tr2>
210
    inline void iterator_adaptor_assert_traversal ()
211
    {
212
      BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
213
    }
214
  }
215
216
  //
217
  // Iterator Adaptor
218
  //
219
  // The parameter ordering changed slightly with respect to former
220
  // versions of iterator_adaptor The idea is that when the user needs
221
  // to fiddle with the reference type it is highly likely that the
222
  // iterator category has to be adjusted as well.  Any of the
223
  // following four template arguments may be ommitted or explicitly
224
  // replaced by use_default.
225
  //
226
  //   Value - if supplied, the value_type of the resulting iterator, unless
227
  //      const. If const, a conforming compiler strips constness for the
228
  //      value_type. If not supplied, iterator_traits<Base>::value_type is used
229
  //
230
  //   Category - the traversal category of the resulting iterator. If not
231
  //      supplied, iterator_traversal<Base>::type is used.
232
  //
233
  //   Reference - the reference type of the resulting iterator, and in
234
  //      particular, the result type of operator*(). If not supplied but
235
  //      Value is supplied, Value& is used. Otherwise
236
  //      iterator_traits<Base>::reference is used.
237
  //
238
  //   Difference - the difference_type of the resulting iterator. If not
239
  //      supplied, iterator_traits<Base>::difference_type is used.
240
  //
241
  template <
242
      class Derived
243
    , class Base
244
    , class Value        = use_default
245
    , class Traversal    = use_default
246
    , class Reference    = use_default
247
    , class Difference   = use_default
248
  >
249
  class iterator_adaptor
250
    : public boost::iterators::detail::iterator_adaptor_base<
251
        Derived, Base, Value, Traversal, Reference, Difference
252
      >::type
253
  {
254
      friend class iterator_core_access;
255
256
   protected:
257
      typedef typename boost::iterators::detail::iterator_adaptor_base<
258
          Derived, Base, Value, Traversal, Reference, Difference
259
      >::type super_t;
260
   public:
261
      iterator_adaptor() {}
262
263
      explicit iterator_adaptor(Base const &iter)
264
          : m_iterator(iter)
265
12
      {
266
12
      }
267
268
      typedef Base base_type;
269
270
      Base const& base() const
271
114
        { return m_iterator; }
272
273
   protected:
274
      // for convenience in derived classes
275
      typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
276
277
      //
278
      // lvalue access to the Base object for Derived
279
      //
280
      Base const& base_reference() const
281
        { return m_iterator; }
282
283
      Base& base_reference()
284
        { return m_iterator; }
285
286
   private:
287
      //
288
      // Core iterator interface for iterator_facade.  This is private
289
      // to prevent temptation for Derived classes to use it, which
290
      // will often result in an error.  Derived classes should use
291
      // base_reference(), above, to get direct access to m_iterator.
292
      //
293
      typename super_t::reference dereference() const
294
        { return *m_iterator; }
295
296
      template <
297
      class OtherDerived, class OtherIterator, class V, class C, class R, class D
298
      >
299
      bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
300
60
      {
301
        // Maybe readd with same_distance
302
        //           BOOST_STATIC_ASSERT(
303
        //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
304
        //               );
305
60
          return m_iterator == x.base();
306
60
      }
307
308
      typedef typename iterator_category_to_traversal<
309
          typename super_t::iterator_category
310
      >::type my_traversal;
311
312
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
313
      boost::iterators::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
314
315
      void advance(typename super_t::difference_type n)
316
      {
317
          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
318
          m_iterator += n;
319
      }
320
321
54
      void increment() { ++m_iterator; }
322
323
      void decrement()
324
      {
325
          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
326
           --m_iterator;
327
      }
328
329
      template <
330
          class OtherDerived, class OtherIterator, class V, class C, class R, class D
331
      >
332
      typename super_t::difference_type distance_to(
333
          iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
334
      {
335
          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
336
          // Maybe readd with same_distance
337
          //           BOOST_STATIC_ASSERT(
338
          //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
339
          //               );
340
          return y.base() - m_iterator;
341
      }
342
343
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
344
345
   private: // data members
346
      Base m_iterator;
347
  };
348
349
} // namespace iterators
350
351
using iterators::iterator_adaptor;
352
using iterators::enable_if_convertible;
353
354
} // namespace boost
355
356
#include <boost/iterator/detail/config_undef.hpp>
357
358
#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/iterator/iterator_facade.hpp
Line
Count
Source
1
// (C) Copyright David Abrahams 2002.
2
// (C) Copyright Jeremy Siek    2002.
3
// (C) Copyright Thomas Witt    2002.
4
// Distributed under the Boost Software License, Version 1.0. (See
5
// accompanying file LICENSE_1_0.txt or copy at
6
// http://www.boost.org/LICENSE_1_0.txt)
7
#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
8
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
9
10
#include <boost/config.hpp>
11
#include <boost/iterator/interoperable.hpp>
12
#include <boost/iterator/iterator_traits.hpp>
13
#include <boost/iterator/iterator_categories.hpp>
14
15
#include <boost/iterator/detail/facade_iterator_category.hpp>
16
#include <boost/iterator/detail/enable_if.hpp>
17
18
#include <boost/static_assert.hpp>
19
#include <boost/core/addressof.hpp>
20
21
#include <boost/type_traits/is_same.hpp>
22
#include <boost/type_traits/add_const.hpp>
23
#include <boost/type_traits/add_pointer.hpp>
24
#include <boost/type_traits/add_lvalue_reference.hpp>
25
#include <boost/type_traits/remove_const.hpp>
26
#include <boost/type_traits/remove_reference.hpp>
27
#include <boost/type_traits/is_convertible.hpp>
28
#include <boost/type_traits/is_pod.hpp>
29
30
#include <boost/mpl/eval_if.hpp>
31
#include <boost/mpl/if.hpp>
32
#include <boost/mpl/or.hpp>
33
#include <boost/mpl/and.hpp>
34
#include <boost/mpl/not.hpp>
35
#include <boost/mpl/always.hpp>
36
#include <boost/mpl/apply.hpp>
37
#include <boost/mpl/identity.hpp>
38
39
#include <cstddef>
40
41
#include <boost/iterator/detail/config_def.hpp> // this goes last
42
43
namespace boost {
44
namespace iterators {
45
46
  // This forward declaration is required for the friend declaration
47
  // in iterator_core_access
48
  template <class I, class V, class TC, class R, class D> class iterator_facade;
49
50
  namespace detail
51
  {
52
    // A binary metafunction class that always returns bool.  VC6
53
    // ICEs on mpl::always<bool>, probably because of the default
54
    // parameters.
55
    struct always_bool2
56
    {
57
        template <class T, class U>
58
        struct apply
59
        {
60
            typedef bool type;
61
        };
62
    };
63
64
    // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
65
    template< typename CategoryOrTraversal, typename Required >
66
    struct is_traversal_at_least :
67
        public boost::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
68
    {};
69
70
    //
71
    // enable if for use in operator implementation.
72
    //
73
    template <
74
        class Facade1
75
      , class Facade2
76
      , class Return
77
    >
78
    struct enable_if_interoperable :
79
        public boost::iterators::enable_if<
80
            is_interoperable< Facade1, Facade2 >
81
          , Return
82
        >
83
    {};
84
85
    //
86
    // enable if for use in implementation of operators specific for random access traversal.
87
    //
88
    template <
89
        class Facade1
90
      , class Facade2
91
      , class Return
92
    >
93
    struct enable_if_interoperable_and_random_access_traversal :
94
        public boost::iterators::enable_if<
95
            mpl::and_<
96
                is_interoperable< Facade1, Facade2 >
97
              , is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >
98
              , is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
99
            >
100
          , Return
101
        >
102
    {};
103
104
    //
105
    // Generates associated types for an iterator_facade with the
106
    // given parameters.
107
    //
108
    template <
109
        class ValueParam
110
      , class CategoryOrTraversal
111
      , class Reference
112
      , class Difference
113
    >
114
    struct iterator_facade_types
115
    {
116
        typedef typename facade_iterator_category<
117
            CategoryOrTraversal, ValueParam, Reference
118
        >::type iterator_category;
119
120
        typedef typename remove_const<ValueParam>::type value_type;
121
122
        // Not the real associated pointer type
123
        typedef typename mpl::eval_if<
124
            boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference>
125
          , add_pointer<const value_type>
126
          , add_pointer<value_type>
127
        >::type pointer;
128
129
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)                          \
130
    && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452))              \
131
        || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310)))     \
132
    || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101))              \
133
    || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
134
135
        // To interoperate with some broken library/compiler
136
        // combinations, user-defined iterators must be derived from
137
        // std::iterator.  It is possible to implement a standard
138
        // library for broken compilers without this limitation.
139
#  define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
140
141
        typedef
142
           iterator<iterator_category, value_type, Difference, pointer, Reference>
143
        base;
144
# endif
145
    };
146
147
    // iterators whose dereference operators reference the same value
148
    // for all iterators into the same sequence (like many input
149
    // iterators) need help with their postfix ++: the referenced
150
    // value must be read and stored away before the increment occurs
151
    // so that *a++ yields the originally referenced element and not
152
    // the next one.
153
    template <class Iterator>
154
    class postfix_increment_proxy
155
    {
156
        typedef typename iterator_value<Iterator>::type value_type;
157
     public:
158
        explicit postfix_increment_proxy(Iterator const& x)
159
          : stored_value(*x)
160
        {}
161
162
        // Returning a mutable reference allows nonsense like
163
        // (*r++).mutate(), but it imposes fewer assumptions about the
164
        // behavior of the value_type.  In particular, recall that
165
        // (*r).mutate() is legal if operator* returns by value.
166
        value_type&
167
        operator*() const
168
        {
169
            return this->stored_value;
170
        }
171
     private:
172
        mutable value_type stored_value;
173
    };
174
175
    //
176
    // In general, we can't determine that such an iterator isn't
177
    // writable -- we also need to store a copy of the old iterator so
178
    // that it can be written into.
179
    template <class Iterator>
180
    class writable_postfix_increment_proxy
181
    {
182
        typedef typename iterator_value<Iterator>::type value_type;
183
     public:
184
        explicit writable_postfix_increment_proxy(Iterator const& x)
185
          : stored_value(*x)
186
          , stored_iterator(x)
187
        {}
188
189
        // Dereferencing must return a proxy so that both *r++ = o and
190
        // value_type(*r++) can work.  In this case, *r is the same as
191
        // *r++, and the conversion operator below is used to ensure
192
        // readability.
193
        writable_postfix_increment_proxy const&
194
        operator*() const
195
        {
196
            return *this;
197
        }
198
199
        // Provides readability of *r++
200
        operator value_type&() const
201
        {
202
            return stored_value;
203
        }
204
205
        // Provides writability of *r++
206
        template <class T>
207
        T const& operator=(T const& x) const
208
        {
209
            *this->stored_iterator = x;
210
            return x;
211
        }
212
213
        // This overload just in case only non-const objects are writable
214
        template <class T>
215
        T& operator=(T& x) const
216
        {
217
            *this->stored_iterator = x;
218
            return x;
219
        }
220
221
        // Provides X(r++)
222
        operator Iterator const&() const
223
        {
224
            return stored_iterator;
225
        }
226
227
     private:
228
        mutable value_type stored_value;
229
        Iterator stored_iterator;
230
    };
231
232
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
233
234
    template <class Reference, class Value>
235
    struct is_non_proxy_reference_impl
236
    {
237
        static Reference r;
238
239
        template <class R>
240
        static typename mpl::if_<
241
            is_convertible<
242
                R const volatile*
243
              , Value const volatile*
244
            >
245
          , char[1]
246
          , char[2]
247
        >::type& helper(R const&);
248
249
        BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
250
    };
251
252
    template <class Reference, class Value>
253
    struct is_non_proxy_reference
254
      : mpl::bool_<
255
            is_non_proxy_reference_impl<Reference, Value>::value
256
        >
257
    {};
258
# else
259
    template <class Reference, class Value>
260
    struct is_non_proxy_reference
261
      : is_convertible<
262
            typename remove_reference<Reference>::type
263
            const volatile*
264
          , Value const volatile*
265
        >
266
    {};
267
# endif
268
269
    // A metafunction to choose the result type of postfix ++
270
    //
271
    // Because the C++98 input iterator requirements say that *r++ has
272
    // type T (value_type), implementations of some standard
273
    // algorithms like lexicographical_compare may use constructions
274
    // like:
275
    //
276
    //          *r++ < *s++
277
    //
278
    // If *r++ returns a proxy (as required if r is writable but not
279
    // multipass), this sort of expression will fail unless the proxy
280
    // supports the operator<.  Since there are any number of such
281
    // operations, we're not going to try to support them.  Therefore,
282
    // even if r++ returns a proxy, *r++ will only return a proxy if
283
    // *r also returns a proxy.
284
    template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
285
    struct postfix_increment_result
286
      : mpl::eval_if<
287
            mpl::and_<
288
                // A proxy is only needed for readable iterators
289
                is_convertible<
290
                    Reference
291
                    // Use add_lvalue_reference to form `reference to Value` due to
292
                    // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
293
                    // 'reference-to-reference' in the template which described in CWG
294
                    // DR106.
295
                    // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
296
                  , typename add_lvalue_reference<Value const>::type
297
                >
298
299
                // No multipass iterator can have values that disappear
300
                // before positions can be re-visited
301
              , mpl::not_<
302
                    is_convertible<
303
                        typename iterator_category_to_traversal<CategoryOrTraversal>::type
304
                      , forward_traversal_tag
305
                    >
306
                >
307
            >
308
          , mpl::if_<
309
                is_non_proxy_reference<Reference,Value>
310
              , postfix_increment_proxy<Iterator>
311
              , writable_postfix_increment_proxy<Iterator>
312
            >
313
          , mpl::identity<Iterator>
314
        >
315
    {};
316
317
    // operator->() needs special support for input iterators to strictly meet the
318
    // standard's requirements. If *i is not a reference type, we must still
319
    // produce an lvalue to which a pointer can be formed.  We do that by
320
    // returning a proxy object containing an instance of the reference object.
321
    template <class Reference, class Pointer>
322
    struct operator_arrow_dispatch // proxy references
323
    {
324
        struct proxy
325
        {
326
            explicit proxy(Reference const & x) : m_ref(x) {}
327
            Reference* operator->() { return boost::addressof(m_ref); }
328
            // This function is needed for MWCW and BCC, which won't call
329
            // operator-> again automatically per 13.3.1.2 para 8
330
            operator Reference*() { return boost::addressof(m_ref); }
331
            Reference m_ref;
332
        };
333
        typedef proxy result_type;
334
        static result_type apply(Reference const & x)
335
        {
336
            return result_type(x);
337
        }
338
    };
339
340
    template <class T, class Pointer>
341
    struct operator_arrow_dispatch<T&, Pointer> // "real" references
342
    {
343
        typedef Pointer result_type;
344
        static result_type apply(T& x)
345
        {
346
            return boost::addressof(x);
347
        }
348
    };
349
350
    // A proxy return type for operator[], needed to deal with
351
    // iterators that may invalidate referents upon destruction.
352
    // Consider the temporary iterator in *(a + n)
353
    template <class Iterator>
354
    class operator_brackets_proxy
355
    {
356
        // Iterator is actually an iterator_facade, so we do not have to
357
        // go through iterator_traits to access the traits.
358
        typedef typename Iterator::reference  reference;
359
        typedef typename Iterator::value_type value_type;
360
361
     public:
362
        operator_brackets_proxy(Iterator const& iter)
363
          : m_iter(iter)
364
        {}
365
366
        operator reference() const
367
        {
368
            return *m_iter;
369
        }
370
371
        operator_brackets_proxy& operator=(value_type const& val)
372
        {
373
            *m_iter = val;
374
            return *this;
375
        }
376
377
     private:
378
        Iterator m_iter;
379
    };
380
381
    // A metafunction that determines whether operator[] must return a
382
    // proxy, or whether it can simply return a copy of the value_type.
383
    template <class ValueType, class Reference>
384
    struct use_operator_brackets_proxy
385
      : mpl::not_<
386
            mpl::and_<
387
                // Really we want an is_copy_constructible trait here,
388
                // but is_POD will have to suffice in the meantime.
389
                boost::is_POD<ValueType>
390
              , iterator_writability_disabled<ValueType,Reference>
391
            >
392
        >
393
    {};
394
395
    template <class Iterator, class Value, class Reference>
396
    struct operator_brackets_result
397
    {
398
        typedef typename mpl::if_<
399
            use_operator_brackets_proxy<Value,Reference>
400
          , operator_brackets_proxy<Iterator>
401
          , Value
402
        >::type type;
403
    };
404
405
    template <class Iterator>
406
    operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
407
    {
408
        return operator_brackets_proxy<Iterator>(iter);
409
    }
410
411
    template <class Iterator>
412
    typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
413
    {
414
      return *iter;
415
    }
416
417
    struct choose_difference_type
418
    {
419
        template <class I1, class I2>
420
        struct apply
421
          :
422
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
423
          iterator_difference<I1>
424
# else
425
          mpl::eval_if<
426
              is_convertible<I2,I1>
427
            , iterator_difference<I1>
428
            , iterator_difference<I2>
429
          >
430
# endif
431
        {};
432
433
    };
434
435
    template <
436
        class Derived
437
      , class Value
438
      , class CategoryOrTraversal
439
      , class Reference
440
      , class Difference
441
      , bool IsBidirectionalTraversal
442
      , bool IsRandomAccessTraversal
443
    >
444
    class iterator_facade_base;
445
446
  } // namespace detail
447
448
449
  // Macros which describe the declarations of binary operators
450
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
451
#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler)       \
452
    template <                                                              \
453
        class Derived1, class V1, class TC1, class Reference1, class Difference1 \
454
      , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
455
    >                                                                       \
456
    prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
457
    operator op(                                                            \
458
        iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs   \
459
      , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
460
# else
461
#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler)   \
462
    template <                                                          \
463
        class Derived1, class V1, class TC1, class Reference1, class Difference1 \
464
      , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
465
    >                                                                   \
466
    prefix typename enabler<                                            \
467
        Derived1, Derived2                                              \
468
      , typename mpl::apply2<result_type,Derived1,Derived2>::type       \
469
    >::type                                                             \
470
    operator op(                                                        \
471
        iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs   \
472
      , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
473
# endif
474
475
#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)       \
476
    BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
477
478
#  define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type)       \
479
    BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
480
481
#  define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args)              \
482
    template <class Derived, class V, class TC, class R, class D>   \
483
    prefix typename boost::iterators::enable_if<                    \
484
        boost::iterators::detail::is_traversal_at_least< TC, boost::iterators::random_access_traversal_tag >,  \
485
        Derived                                                     \
486
    >::type operator+ args
487
488
  //
489
  // Helper class for granting access to the iterator core interface.
490
  //
491
  // The simple core interface is used by iterator_facade. The core
492
  // interface of a user/library defined iterator type should not be made public
493
  // so that it does not clutter the public interface. Instead iterator_core_access
494
  // should be made friend so that iterator_facade can access the core
495
  // interface through iterator_core_access.
496
  //
497
  class iterator_core_access
498
  {
499
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
500
      // Tasteless as this may seem, making all members public allows member templates
501
      // to work in the absence of member template friends.
502
   public:
503
# else
504
505
      template <class I, class V, class TC, class R, class D> friend class iterator_facade;
506
      template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal>
507
      friend class detail::iterator_facade_base;
508
509
#  define BOOST_ITERATOR_FACADE_RELATION(op)                                \
510
      BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::iterators::detail::always_bool2);
511
512
      BOOST_ITERATOR_FACADE_RELATION(==)
513
      BOOST_ITERATOR_FACADE_RELATION(!=)
514
515
#  undef BOOST_ITERATOR_FACADE_RELATION
516
517
#  define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op)                                \
518
      BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend,op, boost::iterators::detail::always_bool2);
519
520
      BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
521
      BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
522
      BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
523
      BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
524
525
#  undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
526
527
      BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(
528
          friend, -, boost::iterators::detail::choose_difference_type)
529
      ;
530
531
      BOOST_ITERATOR_FACADE_PLUS_HEAD(
532
          friend inline
533
        , (iterator_facade<Derived, V, TC, R, D> const&
534
        , typename Derived::difference_type)
535
      )
536
      ;
537
538
      BOOST_ITERATOR_FACADE_PLUS_HEAD(
539
          friend inline
540
        , (typename Derived::difference_type
541
        , iterator_facade<Derived, V, TC, R, D> const&)
542
      )
543
      ;
544
545
# endif
546
547
      template <class Facade>
548
      static typename Facade::reference dereference(Facade const& f)
549
108
      {
550
108
          return f.dereference();
551
108
      }
_ZN5boost9iterators20iterator_core_access11dereferenceINS0_18transform_iteratorINS_9algorithm6detail20copy_iterator_rangeFINSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEENS7_11__wrap_iterIPKcEEEENS4_14split_iteratorISH_EENS_11use_defaultESL_EEEENT_9referenceERKSN_
Line
Count
Source
549
54
      {
550
54
          return f.dereference();
551
54
      }
_ZN5boost9iterators20iterator_core_access11dereferenceINS_9algorithm14split_iteratorINSt3__111__wrap_iterIPKcEEEEEENT_9referenceERKSB_
Line
Count
Source
549
54
      {
550
54
          return f.dereference();
551
54
      }
552
553
      template <class Facade>
554
      static void increment(Facade& f)
555
108
      {
556
108
          f.increment();
557
108
      }
_ZN5boost9iterators20iterator_core_access9incrementINS0_18transform_iteratorINS_9algorithm6detail20copy_iterator_rangeFINSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEENS7_11__wrap_iterIPKcEEEENS4_14split_iteratorISH_EENS_11use_defaultESL_EEEEvRT_
Line
Count
Source
555
54
      {
556
54
          f.increment();
557
54
      }
_ZN5boost9iterators20iterator_core_access9incrementINS_9algorithm14split_iteratorINSt3__111__wrap_iterIPKcEEEEEEvRT_
Line
Count
Source
555
54
      {
556
54
          f.increment();
557
54
      }
558
559
      template <class Facade>
560
      static void decrement(Facade& f)
561
      {
562
          f.decrement();
563
      }
564
565
      template <class Facade1, class Facade2>
566
      static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
567
120
      {
568
120
          return f1.equal(f2);
569
120
      }
_ZN5boost9iterators20iterator_core_access5equalINS0_18transform_iteratorINS_9algorithm6detail20copy_iterator_rangeFINSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEENS7_11__wrap_iterIPKcEEEENS4_14split_iteratorISH_EENS_11use_defaultESL_EESM_EEbRKT_RKT0_N4mpl_5bool_ILb1EEE
Line
Count
Source
567
60
      {
568
60
          return f1.equal(f2);
569
60
      }
_ZN5boost9iterators20iterator_core_access5equalINS_9algorithm14split_iteratorINSt3__111__wrap_iterIPKcEEEESA_EEbRKT_RKT0_N4mpl_5bool_ILb1EEE
Line
Count
Source
567
60
      {
568
60
          return f1.equal(f2);
569
60
      }
570
571
      template <class Facade1, class Facade2>
572
      static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
573
      {
574
          return f2.equal(f1);
575
      }
576
577
      template <class Facade>
578
      static void advance(Facade& f, typename Facade::difference_type n)
579
      {
580
          f.advance(n);
581
      }
582
583
      template <class Facade1, class Facade2>
584
      static typename Facade1::difference_type distance_from(
585
          Facade1 const& f1, Facade2 const& f2, mpl::true_)
586
      {
587
          return -f1.distance_to(f2);
588
      }
589
590
      template <class Facade1, class Facade2>
591
      static typename Facade2::difference_type distance_from(
592
          Facade1 const& f1, Facade2 const& f2, mpl::false_)
593
      {
594
          return f2.distance_to(f1);
595
      }
596
597
      //
598
      // Curiously Recurring Template interface.
599
      //
600
      template <class I, class V, class TC, class R, class D>
601
      static I& derived(iterator_facade<I,V,TC,R,D>& facade)
602
      {
603
          return *static_cast<I*>(&facade);
604
      }
605
606
      template <class I, class V, class TC, class R, class D>
607
      static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
608
      {
609
          return *static_cast<I const*>(&facade);
610
      }
611
612
      // objects of this class are useless
613
      BOOST_DELETED_FUNCTION(iterator_core_access())
614
  };
615
616
  namespace detail {
617
618
    // Implementation for forward traversal iterators
619
    template <
620
        class Derived
621
      , class Value
622
      , class CategoryOrTraversal
623
      , class Reference
624
      , class Difference
625
    >
626
    class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
627
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
628
        : public boost::iterators::detail::iterator_facade_types<
629
             Value, CategoryOrTraversal, Reference, Difference
630
          >::base
631
#  undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
632
# endif
633
    {
634
    private:
635
        typedef boost::iterators::detail::iterator_facade_types<
636
            Value, CategoryOrTraversal, Reference, Difference
637
        > associated_types;
638
639
        typedef boost::iterators::detail::operator_arrow_dispatch<
640
            Reference
641
          , typename associated_types::pointer
642
        > operator_arrow_dispatch_;
643
644
    public:
645
        typedef typename associated_types::value_type value_type;
646
        typedef Reference reference;
647
        typedef Difference difference_type;
648
649
        typedef typename operator_arrow_dispatch_::result_type pointer;
650
651
        typedef typename associated_types::iterator_category iterator_category;
652
653
    public:
654
        reference operator*() const
655
108
        {
656
108
            return iterator_core_access::dereference(this->derived());
657
108
        }
_ZNK5boost9iterators6detail20iterator_facade_baseINS0_18transform_iteratorINS_9algorithm6detail20copy_iterator_rangeFINSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEENS7_11__wrap_iterIPKcEEEENS4_14split_iteratorISH_EENS_11use_defaultESL_EESD_NS0_21forward_traversal_tagESD_lLb0ELb0EEdeEv
Line
Count
Source
655
54
        {
656
54
            return iterator_core_access::dereference(this->derived());
657
54
        }
_ZNK5boost9iterators6detail20iterator_facade_baseINS_9algorithm14split_iteratorINSt3__111__wrap_iterIPKcEEEEKNS_14iterator_rangeIS9_EENS0_21forward_traversal_tagERSD_lLb0ELb0EEdeEv
Line
Count
Source
655
54
        {
656
54
            return iterator_core_access::dereference(this->derived());
657
54
        }
658
659
        pointer operator->() const
660
        {
661
            return operator_arrow_dispatch_::apply(*this->derived());
662
        }
663
664
        Derived& operator++()
665
108
        {
666
108
            iterator_core_access::increment(this->derived());
667
108
            return this->derived();
668
108
        }
_ZN5boost9iterators6detail20iterator_facade_baseINS0_18transform_iteratorINS_9algorithm6detail20copy_iterator_rangeFINSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEENS7_11__wrap_iterIPKcEEEENS4_14split_iteratorISH_EENS_11use_defaultESL_EESD_NS0_21forward_traversal_tagESD_lLb0ELb0EEppEv
Line
Count
Source
665
54
        {
666
54
            iterator_core_access::increment(this->derived());
667
54
            return this->derived();
668
54
        }
_ZN5boost9iterators6detail20iterator_facade_baseINS_9algorithm14split_iteratorINSt3__111__wrap_iterIPKcEEEEKNS_14iterator_rangeIS9_EENS0_21forward_traversal_tagERSD_lLb0ELb0EEppEv
Line
Count
Source
665
54
        {
666
54
            iterator_core_access::increment(this->derived());
667
54
            return this->derived();
668
54
        }
669
670
    protected:
671
        //
672
        // Curiously Recurring Template interface.
673
        //
674
        Derived& derived()
675
216
        {
676
216
            return *static_cast<Derived*>(this);
677
216
        }
_ZN5boost9iterators6detail20iterator_facade_baseINS_9algorithm14split_iteratorINSt3__111__wrap_iterIPKcEEEEKNS_14iterator_rangeIS9_EENS0_21forward_traversal_tagERSD_lLb0ELb0EE7derivedEv
Line
Count
Source
675
108
        {
676
108
            return *static_cast<Derived*>(this);
677
108
        }
_ZN5boost9iterators6detail20iterator_facade_baseINS0_18transform_iteratorINS_9algorithm6detail20copy_iterator_rangeFINSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEENS7_11__wrap_iterIPKcEEEENS4_14split_iteratorISH_EENS_11use_defaultESL_EESD_NS0_21forward_traversal_tagESD_lLb0ELb0EE7derivedEv
Line
Count
Source
675
108
        {
676
108
            return *static_cast<Derived*>(this);
677
108
        }
678
679
        Derived const& derived() const
680
108
        {
681
108
            return *static_cast<Derived const*>(this);
682
108
        }
_ZNK5boost9iterators6detail20iterator_facade_baseINS_9algorithm14split_iteratorINSt3__111__wrap_iterIPKcEEEEKNS_14iterator_rangeIS9_EENS0_21forward_traversal_tagERSD_lLb0ELb0EE7derivedEv
Line
Count
Source
680
54
        {
681
54
            return *static_cast<Derived const*>(this);
682
54
        }
_ZNK5boost9iterators6detail20iterator_facade_baseINS0_18transform_iteratorINS_9algorithm6detail20copy_iterator_rangeFINSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEENS7_11__wrap_iterIPKcEEEENS4_14split_iteratorISH_EENS_11use_defaultESL_EESD_NS0_21forward_traversal_tagESD_lLb0ELb0EE7derivedEv
Line
Count
Source
680
54
        {
681
54
            return *static_cast<Derived const*>(this);
682
54
        }
683
    };
684
685
    // Implementation for bidirectional traversal iterators
686
    template <
687
        class Derived
688
      , class Value
689
      , class CategoryOrTraversal
690
      , class Reference
691
      , class Difference
692
    >
693
    class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
694
        public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
695
    {
696
    public:
697
        Derived& operator--()
698
        {
699
            iterator_core_access::decrement(this->derived());
700
            return this->derived();
701
        }
702
703
        Derived operator--(int)
704
        {
705
            Derived tmp(this->derived());
706
            --*this;
707
            return tmp;
708
        }
709
    };
710
711
    // Implementation for random access traversal iterators
712
    template <
713
        class Derived
714
      , class Value
715
      , class CategoryOrTraversal
716
      , class Reference
717
      , class Difference
718
    >
719
    class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
720
        public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
721
    {
722
    private:
723
        typedef iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > base_type;
724
725
    public:
726
        typedef typename base_type::reference reference;
727
        typedef typename base_type::difference_type difference_type;
728
729
    public:
730
        typename boost::iterators::detail::operator_brackets_result<Derived, Value, reference>::type
731
        operator[](difference_type n) const
732
        {
733
            typedef boost::iterators::detail::use_operator_brackets_proxy<Value, Reference> use_proxy;
734
735
            return boost::iterators::detail::make_operator_brackets_result<Derived>(
736
                this->derived() + n
737
              , use_proxy()
738
            );
739
        }
740
741
        Derived& operator+=(difference_type n)
742
        {
743
            iterator_core_access::advance(this->derived(), n);
744
            return this->derived();
745
        }
746
747
        Derived& operator-=(difference_type n)
748
        {
749
            iterator_core_access::advance(this->derived(), -n);
750
            return this->derived();
751
        }
752
753
        Derived operator-(difference_type x) const
754
        {
755
            Derived result(this->derived());
756
            return result -= x;
757
        }
758
    };
759
760
  } // namespace detail
761
762
  //
763
  // iterator_facade - use as a public base class for defining new
764
  // standard-conforming iterators.
765
  //
766
  template <
767
      class Derived             // The derived iterator type being constructed
768
    , class Value
769
    , class CategoryOrTraversal
770
    , class Reference   = Value&
771
    , class Difference  = std::ptrdiff_t
772
  >
773
  class iterator_facade :
774
      public detail::iterator_facade_base<
775
          Derived,
776
          Value,
777
          CategoryOrTraversal,
778
          Reference,
779
          Difference,
780
          detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
781
          detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
782
      >
783
  {
784
  protected:
785
      // For use by derived classes
786
      typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
787
  };
788
789
  template <class I, class V, class TC, class R, class D>
790
  inline typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
791
  operator++(
792
      iterator_facade<I,V,TC,R,D>& i
793
    , int
794
  )
795
  {
796
      typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
797
          tmp(*static_cast<I*>(&i));
798
799
      ++i;
800
801
      return tmp;
802
  }
803
804
805
  //
806
  // Comparison operator implementation. The library supplied operators
807
  // enables the user to provide fully interoperable constant/mutable
808
  // iterator types. I.e. the library provides all operators
809
  // for all mutable/constant iterator combinations.
810
  //
811
  // Note though that this kind of interoperability for constant/mutable
812
  // iterators is not required by the standard for container iterators.
813
  // All the standard asks for is a conversion mutable -> constant.
814
  // Most standard library implementations nowadays provide fully interoperable
815
  // iterator implementations, but there are still heavily used implementations
816
  // that do not provide them. (Actually it's even worse, they do not provide
817
  // them for only a few iterators.)
818
  //
819
  // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
820
  //    enable the user to turn off mixed type operators
821
  //
822
  // The library takes care to provide only the right operator overloads.
823
  // I.e.
824
  //
825
  // bool operator==(Iterator,      Iterator);
826
  // bool operator==(ConstIterator, Iterator);
827
  // bool operator==(Iterator,      ConstIterator);
828
  // bool operator==(ConstIterator, ConstIterator);
829
  //
830
  //   ...
831
  //
832
  // In order to do so it uses c++ idioms that are not yet widely supported
833
  // by current compiler releases. The library is designed to degrade gracefully
834
  // in the face of compiler deficiencies. In general compiler
835
  // deficiencies result in less strict error checking and more obscure
836
  // error messages, functionality is not affected.
837
  //
838
  // For full operation compiler support for "Substitution Failure Is Not An Error"
839
  // (aka. enable_if) and boost::is_convertible is required.
840
  //
841
  // The following problems occur if support is lacking.
842
  //
843
  // Pseudo code
844
  //
845
  // ---------------
846
  // AdaptorA<Iterator1> a1;
847
  // AdaptorA<Iterator2> a2;
848
  //
849
  // // This will result in a no such overload error in full operation
850
  // // If enable_if or is_convertible is not supported
851
  // // The instantiation will fail with an error hopefully indicating that
852
  // // there is no operator== for Iterator1, Iterator2
853
  // // The same will happen if no enable_if is used to remove
854
  // // false overloads from the templated conversion constructor
855
  // // of AdaptorA.
856
  //
857
  // a1 == a2;
858
  // ----------------
859
  //
860
  // AdaptorA<Iterator> a;
861
  // AdaptorB<Iterator> b;
862
  //
863
  // // This will result in a no such overload error in full operation
864
  // // If enable_if is not supported the static assert used
865
  // // in the operator implementation will fail.
866
  // // This will accidently work if is_convertible is not supported.
867
  //
868
  // a == b;
869
  // ----------------
870
  //
871
872
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
873
#  define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
874
# else
875
120
#  define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
876
# endif
877
878
# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
879
  BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type)                   \
880
120
  {                                                                             \
881
120
      /* For those compilers that do not support enable_if */                   \
882
120
      BOOST_STATIC_ASSERT((                                                     \
883
120
          is_interoperable< Derived1, Derived2 >::value                         \
884
120
      ));                                                                       \
885
120
      return_prefix iterator_core_access::base_op(                              \
886
120
          *static_cast<Derived1 const*>(&lhs)                                   \
887
120
        , *static_cast<Derived2 const*>(&rhs)                                   \
888
120
        , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
889
120
      );                                                                        \
890
120
  }
_ZN5boost9iteratorsneINS0_18transform_iteratorINS_9algorithm6detail20copy_iterator_rangeFINSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEENS6_11__wrap_iterIPKcEEEENS3_14split_iteratorISG_EENS_11use_defaultESK_EESC_NS0_21forward_traversal_tagESC_lSL_SC_SM_SC_lEENS0_6detail23enable_if_interoperableIT_T4_NS_3mpl6apply2INSN_12always_bool2ESP_SQ_E4typeEE4typeERKNS0_15iterator_facadeISP_T0_T1_T2_T3_EERKNSY_ISQ_T5_T6_T7_T8_EE
Line
Count
Source
880
60
  {                                                                             \
881
60
      /* For those compilers that do not support enable_if */                   \
882
60
      BOOST_STATIC_ASSERT((                                                     \
883
60
          is_interoperable< Derived1, Derived2 >::value                         \
884
60
      ));                                                                       \
885
60
      return_prefix iterator_core_access::base_op(                              \
886
60
          *static_cast<Derived1 const*>(&lhs)                                   \
887
60
        , *static_cast<Derived2 const*>(&rhs)                                   \
888
60
        , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
889
60
      );                                                                        \
890
60
  }
_ZN5boost9iteratorseqINS_9algorithm14split_iteratorINSt3__111__wrap_iterIPKcEEEEKNS_14iterator_rangeIS8_EENS0_21forward_traversal_tagERSC_lS9_SC_SD_SE_lEENS0_6detail23enable_if_interoperableIT_T4_NS_3mpl6apply2INSF_12always_bool2ESH_SI_E4typeEE4typeERKNS0_15iterator_facadeISH_T0_T1_T2_T3_EERKNSQ_ISI_T5_T6_T7_T8_EE
Line
Count
Source
880
60
  {                                                                             \
881
60
      /* For those compilers that do not support enable_if */                   \
882
60
      BOOST_STATIC_ASSERT((                                                     \
883
60
          is_interoperable< Derived1, Derived2 >::value                         \
884
60
      ));                                                                       \
885
60
      return_prefix iterator_core_access::base_op(                              \
886
60
          *static_cast<Derived1 const*>(&lhs)                                   \
887
60
        , *static_cast<Derived2 const*>(&rhs)                                   \
888
60
        , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
889
60
      );                                                                        \
890
60
  }
891
892
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
893
  BOOST_ITERATOR_FACADE_INTEROP(                                    \
894
      op                                                            \
895
    , boost::iterators::detail::always_bool2                                   \
896
    , return_prefix                                                 \
897
    , base_op                                                       \
898
  )
899
900
  BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
901
  BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
902
903
# undef BOOST_ITERATOR_FACADE_RELATION
904
905
906
# define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
907
  BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type)                   \
908
  {                                                                             \
909
      /* For those compilers that do not support enable_if */                   \
910
      BOOST_STATIC_ASSERT((                                                     \
911
          is_interoperable< Derived1, Derived2 >::value &&                      \
912
          boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived1 >::type, random_access_traversal_tag >::value && \
913
          boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived2 >::type, random_access_traversal_tag >::value \
914
      ));                                                                       \
915
      return_prefix iterator_core_access::base_op(                              \
916
          *static_cast<Derived1 const*>(&lhs)                                   \
917
        , *static_cast<Derived2 const*>(&rhs)                                   \
918
        , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
919
      );                                                                        \
920
  }
921
922
# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
923
  BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(                                    \
924
      op                                                            \
925
    , boost::iterators::detail::always_bool2                                   \
926
    , return_prefix                                                 \
927
    , base_op                                                       \
928
  )
929
930
  BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
931
  BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
932
  BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
933
  BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
934
935
# undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
936
937
  // operator- requires an additional part in the static assertion
938
  BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
939
      -
940
    , boost::iterators::detail::choose_difference_type
941
    , return
942
    , distance_from
943
  )
944
945
# undef BOOST_ITERATOR_FACADE_INTEROP
946
# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
947
948
# define BOOST_ITERATOR_FACADE_PLUS(args)           \
949
  BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args)     \
950
  {                                                 \
951
      Derived tmp(static_cast<Derived const&>(i));  \
952
      return tmp += n;                              \
953
  }
954
955
  BOOST_ITERATOR_FACADE_PLUS((
956
      iterator_facade<Derived, V, TC, R, D> const& i
957
    , typename Derived::difference_type n
958
  ))
959
960
  BOOST_ITERATOR_FACADE_PLUS((
961
      typename Derived::difference_type n
962
    , iterator_facade<Derived, V, TC, R, D> const& i
963
  ))
964
965
# undef BOOST_ITERATOR_FACADE_PLUS
966
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
967
968
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
969
# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
970
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
971
972
} // namespace iterators
973
974
using iterators::iterator_core_access;
975
using iterators::iterator_facade;
976
977
} // namespace boost
978
979
#include <boost/iterator/detail/config_undef.hpp>
980
981
#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/iterator/transform_iterator.hpp
Line
Count
Source
1
// (C) Copyright David Abrahams 2002.
2
// (C) Copyright Jeremy Siek    2002.
3
// (C) Copyright Thomas Witt    2002.
4
// Distributed under the Boost Software License, Version 1.0. (See
5
// accompanying file LICENSE_1_0.txt or copy at
6
// http://www.boost.org/LICENSE_1_0.txt)
7
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
8
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
9
10
#include <boost/iterator/detail/enable_if.hpp>
11
#include <boost/iterator/iterator_adaptor.hpp>
12
#include <boost/iterator/iterator_categories.hpp>
13
#include <boost/mpl/not.hpp>
14
#include <boost/mpl/bool.hpp>
15
#include <boost/type_traits/function_traits.hpp>
16
#include <boost/type_traits/is_const.hpp>
17
#include <boost/type_traits/is_class.hpp>
18
#include <boost/type_traits/is_function.hpp>
19
#include <boost/type_traits/is_reference.hpp>
20
#include <boost/type_traits/remove_const.hpp>
21
#include <boost/type_traits/remove_reference.hpp>
22
#include <boost/utility/result_of.hpp>
23
24
#include <iterator>
25
26
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
27
# include <boost/type_traits/is_base_and_derived.hpp>
28
#endif
29
30
#include <boost/iterator/detail/config_def.hpp>
31
32
33
namespace boost {
34
namespace iterators {
35
36
  template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
37
  class transform_iterator;
38
39
  namespace detail
40
  {
41
    // Compute the iterator_adaptor instantiation to be used for transform_iterator
42
    template <class UnaryFunc, class Iterator, class Reference, class Value>
43
    struct transform_iterator_base
44
    {
45
     private:
46
        // By default, dereferencing the iterator yields the same as
47
        // the function.
48
        typedef typename ia_dflt_help<
49
            Reference
50
#ifdef BOOST_RESULT_OF_USE_TR1
51
          , result_of<const UnaryFunc(typename std::iterator_traits<Iterator>::reference)>
52
#else
53
          , result_of<const UnaryFunc&(typename std::iterator_traits<Iterator>::reference)>
54
#endif
55
        >::type reference;
56
57
        // To get the default for Value: remove any reference on the
58
        // result type, but retain any constness to signal
59
        // non-writability.  Note that if we adopt Thomas' suggestion
60
        // to key non-writability *only* on the Reference argument,
61
        // we'd need to strip constness here as well.
62
        typedef typename ia_dflt_help<
63
            Value
64
          , remove_reference<reference>
65
        >::type cv_value_type;
66
67
     public:
68
        typedef iterator_adaptor<
69
            transform_iterator<UnaryFunc, Iterator, Reference, Value>
70
          , Iterator
71
          , cv_value_type
72
          , use_default    // Leave the traversal category alone
73
          , reference
74
        > type;
75
    };
76
  }
77
78
  template <class UnaryFunc, class Iterator, class Reference, class Value>
79
  class transform_iterator
80
    : public boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
81
  {
82
    typedef typename
83
    boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
84
    super_t;
85
86
    friend class iterator_core_access;
87
88
  public:
89
    transform_iterator() { }
90
91
    transform_iterator(Iterator const& x, UnaryFunc f)
92
12
      : super_t(x), m_f(f) { }
93
94
    explicit transform_iterator(Iterator const& x)
95
      : super_t(x)
96
    {
97
        // Pro8 is a little too aggressive about instantiating the
98
        // body of this function.
99
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
100
        // don't provide this constructor if UnaryFunc is a
101
        // function pointer type, since it will be 0.  Too dangerous.
102
        BOOST_STATIC_ASSERT(is_class<UnaryFunc>::value);
103
#endif
104
    }
105
106
    template <
107
        class OtherUnaryFunction
108
      , class OtherIterator
109
      , class OtherReference
110
      , class OtherValue>
111
    transform_iterator(
112
         transform_iterator<OtherUnaryFunction, OtherIterator, OtherReference, OtherValue> const& t
113
       , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
114
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
115
       , typename enable_if_convertible<OtherUnaryFunction, UnaryFunc>::type* = 0
116
#endif
117
    )
118
      : super_t(t.base()), m_f(t.functor())
119
   {}
120
121
    UnaryFunc functor() const
122
      { return m_f; }
123
124
  private:
125
    typename super_t::reference dereference() const
126
54
    { return m_f(*this->base()); }
127
128
    // Probably should be the initial base class so it can be
129
    // optimized away via EBO if it is an empty class.
130
    UnaryFunc m_f;
131
  };
132
133
  template <class UnaryFunc, class Iterator>
134
  inline transform_iterator<UnaryFunc, Iterator>
135
  make_transform_iterator(Iterator it, UnaryFunc fun)
136
12
  {
137
12
      return transform_iterator<UnaryFunc, Iterator>(it, fun);
138
12
  }
139
140
  // Version which allows explicit specification of the UnaryFunc
141
  // type.
142
  //
143
  // This generator is not provided if UnaryFunc is a function
144
  // pointer type, because it's too dangerous: the default-constructed
145
  // function pointer in the iterator be 0, leading to a runtime
146
  // crash.
147
  template <class UnaryFunc, class Iterator>
148
  inline typename iterators::enable_if<
149
      is_class<UnaryFunc>   // We should probably find a cheaper test than is_class<>
150
    , transform_iterator<UnaryFunc, Iterator>
151
  >::type
152
  make_transform_iterator(Iterator it)
153
  {
154
      return transform_iterator<UnaryFunc, Iterator>(it, UnaryFunc());
155
  }
156
157
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
158
  template <class Return, class Argument, class Iterator>
159
  inline transform_iterator< Return (*)(Argument), Iterator, Return>
160
  make_transform_iterator(Iterator it, Return (*fun)(Argument))
161
  {
162
    return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
163
  }
164
#endif
165
166
} // namespace iterators
167
168
using iterators::transform_iterator;
169
using iterators::make_transform_iterator;
170
171
} // namespace boost
172
173
#include <boost/iterator/detail/config_undef.hpp>
174
175
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/none_t.hpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
2
// Copyright (C) 2014, 2015 Andrzej Krzemienski.
3
//
4
// Use, modification, and distribution is subject to the Boost Software
5
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
// http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// See http://www.boost.org/libs/optional for documentation.
9
//
10
// You are welcome to contact the author at:
11
//  fernando_cacciola@hotmail.com
12
//
13
#ifndef BOOST_NONE_T_17SEP2003_HPP
14
#define BOOST_NONE_T_17SEP2003_HPP
15
16
#include <boost/config.hpp>
17
18
namespace boost {
19
20
#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
21
22
namespace detail { struct none_helper{}; }
23
typedef int detail::none_helper::*none_t ;
24
25
#elif defined BOOST_OPTIONAL_USE_SINGLETON_DEFINITION_OF_NONE
26
27
class none_t {};
28
29
#else
30
31
struct none_t
32
{
33
  struct init_tag{};
34
0
  explicit BOOST_CONSTEXPR none_t(init_tag){} // to disable default constructor
35
};
36
37
#endif // old implementation workarounds
38
39
} // namespace boost
40
41
#endif // header guard
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/optional/bad_optional_access.hpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2014, Andrzej Krzemienski.
2
//
3
// Use, modification, and distribution is subject to the Boost Software
4
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5
// http://www.boost.org/LICENSE_1_0.txt)
6
//
7
// See http://www.boost.org/libs/optional for documentation.
8
//
9
// You are welcome to contact the author at:
10
//  akrzemi1@gmail.com
11
//
12
#ifndef BOOST_BAD_OPTIONAL_ACCESS_22MAY2014_HPP
13
#define BOOST_BAD_OPTIONAL_ACCESS_22MAY2014_HPP
14
15
#include <stdexcept>
16
#if __cplusplus < 201103L
17
#include <string> // to make converting-ctor std::string(char const*) visible
18
#endif
19
20
namespace boost {
21
22
#if defined(__clang__)
23
# pragma clang diagnostic push
24
# pragma clang diagnostic ignored "-Wweak-vtables"
25
#endif
26
27
class bad_optional_access : public std::logic_error
28
{
29
public:
30
  bad_optional_access()
31
    : std::logic_error("Attempted to access the value of an uninitialized optional object.")
32
0
    {}
33
};
34
35
#if defined(__clang__)
36
# pragma clang diagnostic pop
37
#endif
38
39
} // namespace boost
40
41
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/optional/optional.hpp
Line
Count
Source
1
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
2
// Copyright (C) 2014 - 2018 Andrzej Krzemienski.
3
//
4
// Use, modification, and distribution is subject to the Boost Software
5
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
// http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// See http://www.boost.org/libs/optional for documentation.
9
//
10
// You are welcome to contact the author at:
11
//  fernando_cacciola@hotmail.com
12
//
13
// Revisions:
14
// 27 Apr 2008 (improved swap) Fernando Cacciola, Niels Dekker, Thorsten Ottosen
15
// 05 May 2014 (Added move semantics) Andrzej Krzemienski
16
//
17
#ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
18
#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
19
20
#include <new>
21
#include <iosfwd>
22
23
#ifdef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
24
#  include <type_traits>
25
#endif
26
27
#include <boost/assert.hpp>
28
#include <boost/core/addressof.hpp>
29
#include <boost/core/enable_if.hpp>
30
#include <boost/core/explicit_operator_bool.hpp>
31
#include <boost/core/swap.hpp>
32
#include <boost/optional/bad_optional_access.hpp>
33
#include <boost/static_assert.hpp>
34
#include <boost/throw_exception.hpp>
35
#include <boost/type.hpp>
36
#include <boost/type_traits/alignment_of.hpp>
37
#include <boost/type_traits/conditional.hpp>
38
#include <boost/type_traits/has_nothrow_constructor.hpp>
39
#include <boost/type_traits/type_with_alignment.hpp>
40
#include <boost/type_traits/remove_const.hpp>
41
#include <boost/type_traits/remove_reference.hpp>
42
#include <boost/type_traits/decay.hpp>
43
#include <boost/type_traits/is_base_of.hpp>
44
#include <boost/type_traits/is_const.hpp>
45
#include <boost/type_traits/is_constructible.hpp>
46
#include <boost/type_traits/is_lvalue_reference.hpp>
47
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
48
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
49
#include <boost/type_traits/is_rvalue_reference.hpp>
50
#include <boost/type_traits/is_same.hpp>
51
#include <boost/type_traits/is_volatile.hpp>
52
#include <boost/type_traits/is_scalar.hpp>
53
#include <boost/move/utility.hpp>
54
#include <boost/none.hpp>
55
#include <boost/utility/compare_pointees.hpp>
56
#include <boost/utility/result_of.hpp>
57
58
#include <boost/optional/optional_fwd.hpp>
59
#include <boost/optional/detail/optional_config.hpp>
60
#include <boost/optional/detail/optional_factory_support.hpp>
61
#include <boost/optional/detail/optional_aligned_storage.hpp>
62
63
namespace boost { namespace optional_detail {
64
65
template <typename T>
66
struct optional_value_type
67
{
68
};
69
70
template <typename T>
71
struct optional_value_type< ::boost::optional<T> >
72
{
73
  typedef T type;
74
};
75
76
}} // namespace boost::optional_detail
77
78
#ifdef BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL
79
#include <boost/optional/detail/old_optional_implementation.hpp>
80
#else
81
namespace boost {
82
83
namespace optional_ns {
84
85
// a tag for in-place initialization of contained value
86
struct in_place_init_t
87
{
88
  struct init_tag{};
89
3
  explicit in_place_init_t(init_tag){}
90
};
91
const in_place_init_t in_place_init ((in_place_init_t::init_tag()));
92
93
// a tag for conditional in-place initialization of contained value
94
struct in_place_init_if_t
95
{
96
  struct init_tag{};
97
3
  explicit in_place_init_if_t(init_tag){}
98
};
99
const in_place_init_if_t in_place_init_if ((in_place_init_if_t::init_tag()));
100
101
} // namespace optional_ns
102
103
using optional_ns::in_place_init_t;
104
using optional_ns::in_place_init;
105
using optional_ns::in_place_init_if_t;
106
using optional_ns::in_place_init_if;
107
108
namespace optional_detail {
109
110
struct init_value_tag {};
111
112
struct optional_tag {};
113
114
115
template<class T>
116
class optional_base : public optional_tag
117
{
118
  private :
119
120
    typedef aligned_storage<T> storage_type ;
121
    typedef optional_base<T> this_type ;
122
123
  protected :
124
125
    typedef T value_type ;
126
127
  protected:
128
    typedef T &       reference_type ;
129
    typedef T const&  reference_const_type ;
130
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
131
    typedef T &&  rval_reference_type ;
132
    typedef T &&  reference_type_of_temporary_wrapper ;
133
#endif
134
    typedef T *         pointer_type ;
135
    typedef T const*    pointer_const_type ;
136
    typedef T const&    argument_type ;
137
138
    // Creates an optional<T> uninitialized.
139
    // No-throw
140
    optional_base()
141
      :
142
      m_initialized(false) {}
143
144
    // Creates an optional<T> uninitialized.
145
    // No-throw
146
    optional_base ( none_t )
147
      :
148
      m_initialized(false) {}
149
150
    // Creates an optional<T> initialized with 'val'.
151
    // Can throw if T::T(T const&) does
152
    optional_base ( init_value_tag, argument_type val )
153
      :
154
      m_initialized(false)
155
    {
156
        construct(val);
157
    }
158
159
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
160
    // move-construct an optional<T> initialized from an rvalue-ref to 'val'.
161
    // Can throw if T::T(T&&) does
162
    optional_base ( init_value_tag, rval_reference_type val )
163
      :
164
      m_initialized(false)
165
    {
166
      construct( boost::move(val) );
167
    }
168
#endif
169
170
    // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional<T>.
171
    // Can throw if T::T(T const&) does
172
    optional_base ( bool cond, argument_type val )
173
      :
174
      m_initialized(false)
175
    {
176
      if ( cond )
177
        construct(val);
178
    }
179
180
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
181
    // Creates an optional<T> initialized with 'move(val)' IFF cond is true, otherwise creates an uninitialized optional<T>.
182
    // Can throw if T::T(T &&) does
183
    optional_base ( bool cond, rval_reference_type val )
184
      :
185
      m_initialized(false)
186
    {
187
      if ( cond )
188
        construct(boost::move(val));
189
    }
190
#endif
191
192
    // Creates a deep copy of another optional<T>
193
    // Can throw if T::T(T const&) does
194
    optional_base ( optional_base const& rhs )
195
      :
196
      m_initialized(false)
197
    {
198
      if ( rhs.is_initialized() )
199
        construct(rhs.get_impl());
200
    }
201
202
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
203
    // Creates a deep move of another optional<T>
204
    // Can throw if T::T(T&&) does
205
    optional_base ( optional_base&& rhs )
206
    BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
207
      :
208
      m_initialized(false)
209
    {
210
      if ( rhs.is_initialized() )
211
        construct( boost::move(rhs.get_impl()) );
212
    }
213
#endif
214
215
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
216
217
    template<class Expr, class PtrExpr>
218
    explicit optional_base ( Expr&& expr, PtrExpr const* tag )
219
      :
220
      m_initialized(false)
221
    {
222
      construct(boost::forward<Expr>(expr),tag);
223
    }
224
225
#else
226
    // This is used for both converting and in-place constructions.
227
    // Derived classes use the 'tag' to select the appropriate
228
    // implementation (the correct 'construct()' overload)
229
    template<class Expr>
230
    explicit optional_base ( Expr const& expr, Expr const* tag )
231
      :
232
      m_initialized(false)
233
    {
234
      construct(expr,tag);
235
    }
236
237
#endif
238
239
    optional_base& operator= ( optional_base const& rhs )
240
    {
241
      this->assign(rhs);
242
      return *this;
243
    }
244
245
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
246
    optional_base& operator= ( optional_base && rhs )
247
    BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
248
    {
249
      this->assign(static_cast<optional_base&&>(rhs));
250
      return *this;
251
    }
252
#endif
253
254
    // No-throw (assuming T::~T() doesn't)
255
    ~optional_base() { destroy() ; }
256
257
    // Assigns from another optional<T> (deep-copies the rhs value)
258
    void assign ( optional_base const& rhs )
259
    {
260
      if (is_initialized())
261
      {
262
        if ( rhs.is_initialized() )
263
             assign_value(rhs.get_impl());
264
        else destroy();
265
      }
266
      else
267
      {
268
        if ( rhs.is_initialized() )
269
          construct(rhs.get_impl());
270
      }
271
    }
272
273
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
274
    // Assigns from another optional<T> (deep-moves the rhs value)
275
    void assign ( optional_base&& rhs )
276
    {
277
      if (is_initialized())
278
      {
279
        if ( rhs.is_initialized() )
280
             assign_value( boost::move(rhs.get_impl()) );
281
        else destroy();
282
      }
283
      else
284
      {
285
        if ( rhs.is_initialized() )
286
          construct(boost::move(rhs.get_impl()));
287
      }
288
    }
289
#endif
290
291
    // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
292
    template<class U>
293
    void assign ( optional<U> const& rhs )
294
    {
295
      if (is_initialized())
296
      {
297
        if ( rhs.is_initialized() )
298
#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
299
          assign_value( rhs.get() );
300
#else
301
          assign_value( static_cast<value_type>(rhs.get()) );
302
#endif
303
304
        else destroy();
305
      }
306
      else
307
      {
308
        if ( rhs.is_initialized() )
309
#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
310
          construct(rhs.get());
311
#else
312
          construct(static_cast<value_type>(rhs.get()));
313
#endif
314
      }
315
    }
316
317
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
318
    // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
319
    template<class U>
320
    void assign ( optional<U>&& rhs )
321
    {
322
      typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
323
      if (is_initialized())
324
      {
325
        if ( rhs.is_initialized() )
326
             assign_value( static_cast<ref_type>(rhs.get()) );
327
        else destroy();
328
      }
329
      else
330
      {
331
        if ( rhs.is_initialized() )
332
          construct(static_cast<ref_type>(rhs.get()));
333
      }
334
    }
335
#endif
336
337
    // Assigns from a T (deep-copies the rhs value)
338
    void assign ( argument_type val )
339
    {
340
      if (is_initialized())
341
           assign_value(val);
342
      else construct(val);
343
    }
344
345
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
346
    // Assigns from a T (deep-moves the rhs value)
347
    void assign ( rval_reference_type val )
348
    {
349
      if (is_initialized())
350
           assign_value( boost::move(val) );
351
      else construct( boost::move(val) );
352
    }
353
#endif
354
355
    // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
356
    // No-throw (assuming T::~T() doesn't)
357
    void assign ( none_t ) BOOST_NOEXCEPT { destroy(); }
358
359
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
360
361
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
362
    template<class Expr, class ExprPtr>
363
    void assign_expr ( Expr&& expr, ExprPtr const* tag )
364
    {
365
      if (is_initialized())
366
        assign_expr_to_initialized(boost::forward<Expr>(expr),tag);
367
      else construct(boost::forward<Expr>(expr),tag);
368
    }
369
#else
370
    template<class Expr>
371
    void assign_expr ( Expr const& expr, Expr const* tag )
372
    {
373
      if (is_initialized())
374
        assign_expr_to_initialized(expr,tag);
375
      else construct(expr,tag);
376
    }
377
#endif
378
379
#endif
380
381
  public :
382
383
    // Destroys the current value, if any, leaving this UNINITIALIZED
384
    // No-throw (assuming T::~T() doesn't)
385
    void reset() BOOST_NOEXCEPT { destroy(); }
386
387
    // **DEPPRECATED** Replaces the current value -if any- with 'val'
388
    void reset ( argument_type val ) { assign(val); }
389
390
    // Returns a pointer to the value if this is initialized, otherwise,
391
    // returns NULL.
392
    // No-throw
393
    pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
394
    pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
395
396
    bool is_initialized() const BOOST_NOEXCEPT { return m_initialized ; }
397
398
  protected :
399
400
    void construct ( argument_type val )
401
     {
402
       ::new (m_storage.address()) value_type(val) ;
403
       m_initialized = true ;
404
     }
405
406
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
407
    void construct ( rval_reference_type val )
408
     {
409
       ::new (m_storage.address()) value_type( boost::move(val) ) ;
410
       m_initialized = true ;
411
     }
412
#endif
413
414
415
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
416
    // Constructs in-place
417
    // upon exception *this is always uninitialized
418
    template<class... Args>
419
    void construct ( in_place_init_t, Args&&... args )
420
    {
421
      ::new (m_storage.address()) value_type( boost::forward<Args>(args)... ) ;
422
      m_initialized = true ;
423
    }
424
425
    template<class... Args>
426
    void emplace_assign ( Args&&... args )
427
    {
428
      destroy();
429
      construct(in_place_init, boost::forward<Args>(args)...);
430
    }
431
432
    template<class... Args>
433
    explicit optional_base ( in_place_init_t, Args&&... args )
434
      :
435
      m_initialized(false)
436
    {
437
      construct(in_place_init, boost::forward<Args>(args)...);
438
    }
439
440
    template<class... Args>
441
    explicit optional_base ( in_place_init_if_t, bool cond, Args&&... args )
442
      :
443
      m_initialized(false)
444
    {
445
      if ( cond )
446
        construct(in_place_init, boost::forward<Args>(args)...);
447
    }
448
#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
449
    template<class Arg>
450
    void construct ( in_place_init_t, Arg&& arg )
451
     {
452
       ::new (m_storage.address()) value_type( boost::forward<Arg>(arg) );
453
       m_initialized = true ;
454
     }
455
456
    void construct ( in_place_init_t )
457
     {
458
       ::new (m_storage.address()) value_type();
459
       m_initialized = true ;
460
     }
461
462
    template<class Arg>
463
    void emplace_assign ( Arg&& arg )
464
     {
465
       destroy();
466
       construct(in_place_init, boost::forward<Arg>(arg)) ;
467
     }
468
469
    void emplace_assign ()
470
     {
471
       destroy();
472
       construct(in_place_init) ;
473
     }
474
475
    template<class Arg>
476
    explicit optional_base ( in_place_init_t, Arg&& arg )
477
      :
478
      m_initialized(false)
479
    {
480
      construct(in_place_init, boost::forward<Arg>(arg));
481
    }
482
483
    explicit optional_base ( in_place_init_t )
484
      :
485
      m_initialized(false)
486
    {
487
      construct(in_place_init);
488
    }
489
490
    template<class Arg>
491
    explicit optional_base ( in_place_init_if_t, bool cond, Arg&& arg )
492
      :
493
      m_initialized(false)
494
    {
495
      if ( cond )
496
        construct(in_place_init, boost::forward<Arg>(arg));
497
    }
498
499
    explicit optional_base ( in_place_init_if_t, bool cond )
500
      :
501
      m_initialized(false)
502
    {
503
      if ( cond )
504
        construct(in_place_init);
505
    }
506
507
#else
508
509
    template<class Arg>
510
    void construct ( in_place_init_t, const Arg& arg )
511
     {
512
       ::new (m_storage.address()) value_type( arg );
513
       m_initialized = true ;
514
     }
515
516
    template<class Arg>
517
    void construct ( in_place_init_t, Arg& arg )
518
     {
519
       ::new (m_storage.address()) value_type( arg );
520
       m_initialized = true ;
521
     }
522
523
    void construct ( in_place_init_t )
524
     {
525
       ::new (m_storage.address()) value_type();
526
       m_initialized = true ;
527
     }
528
529
    template<class Arg>
530
    void emplace_assign ( const Arg& arg )
531
    {
532
      destroy();
533
      construct(in_place_init, arg);
534
    }
535
536
    template<class Arg>
537
    void emplace_assign ( Arg& arg )
538
    {
539
      destroy();
540
      construct(in_place_init, arg);
541
    }
542
543
    void emplace_assign ()
544
    {
545
      destroy();
546
      construct(in_place_init);
547
    }
548
549
    template<class Arg>
550
    explicit optional_base ( in_place_init_t, const Arg& arg )
551
      : m_initialized(false)
552
    {
553
      construct(in_place_init, arg);
554
    }
555
556
    template<class Arg>
557
    explicit optional_base ( in_place_init_t, Arg& arg )
558
      : m_initialized(false)
559
    {
560
      construct(in_place_init, arg);
561
    }
562
563
    explicit optional_base ( in_place_init_t )
564
      : m_initialized(false)
565
    {
566
      construct(in_place_init);
567
    }
568
569
    template<class Arg>
570
    explicit optional_base ( in_place_init_if_t, bool cond, const Arg& arg )
571
      : m_initialized(false)
572
    {
573
      if ( cond )
574
        construct(in_place_init, arg);
575
    }
576
577
    template<class Arg>
578
    explicit optional_base ( in_place_init_if_t, bool cond, Arg& arg )
579
      : m_initialized(false)
580
    {
581
      if ( cond )
582
        construct(in_place_init, arg);
583
    }
584
585
    explicit optional_base ( in_place_init_if_t, bool cond )
586
      : m_initialized(false)
587
    {
588
      if ( cond )
589
        construct(in_place_init);
590
    }
591
#endif
592
593
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
594
595
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
596
    // Constructs in-place using the given factory
597
    template<class Expr>
598
    void construct ( Expr&& factory, in_place_factory_base const* )
599
     {
600
       boost_optional_detail::construct<value_type>(factory, m_storage.address());
601
       m_initialized = true ;
602
     }
603
604
    // Constructs in-place using the given typed factory
605
    template<class Expr>
606
    void construct ( Expr&& factory, typed_in_place_factory_base const* )
607
     {
608
       factory.apply(m_storage.address()) ;
609
       m_initialized = true ;
610
     }
611
612
    template<class Expr>
613
    void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
614
     {
615
       destroy();
616
       construct(factory,tag);
617
     }
618
619
    // Constructs in-place using the given typed factory
620
    template<class Expr>
621
    void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
622
     {
623
       destroy();
624
       construct(factory,tag);
625
     }
626
627
#else
628
    // Constructs in-place using the given factory
629
    template<class Expr>
630
    void construct ( Expr const& factory, in_place_factory_base const* )
631
     {
632
       boost_optional_detail::construct<value_type>(factory, m_storage.address());
633
       m_initialized = true ;
634
     }
635
636
    // Constructs in-place using the given typed factory
637
    template<class Expr>
638
    void construct ( Expr const& factory, typed_in_place_factory_base const* )
639
     {
640
       factory.apply(m_storage.address()) ;
641
       m_initialized = true ;
642
     }
643
644
    template<class Expr>
645
    void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
646
     {
647
       destroy();
648
       construct(factory,tag);
649
     }
650
651
    // Constructs in-place using the given typed factory
652
    template<class Expr>
653
    void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
654
     {
655
       destroy();
656
       construct(factory,tag);
657
     }
658
#endif
659
660
#endif
661
662
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
663
    // Constructs using any expression implicitly convertible to the single argument
664
    // of a one-argument T constructor.
665
    // Converting constructions of optional<T> from optional<U> uses this function with
666
    // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
667
    template<class Expr>
668
    void construct ( Expr&& expr, void const* )
669
    {
670
      new (m_storage.address()) value_type(boost::forward<Expr>(expr)) ;
671
      m_initialized = true ;
672
    }
673
674
    // Assigns using a form any expression implicitly convertible to the single argument
675
    // of a T's assignment operator.
676
    // Converting assignments of optional<T> from optional<U> uses this function with
677
    // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
678
    template<class Expr>
679
    void assign_expr_to_initialized ( Expr&& expr, void const* )
680
    {
681
      assign_value( boost::forward<Expr>(expr) );
682
    }
683
#else
684
    // Constructs using any expression implicitly convertible to the single argument
685
    // of a one-argument T constructor.
686
    // Converting constructions of optional<T> from optional<U> uses this function with
687
    // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
688
    template<class Expr>
689
    void construct ( Expr const& expr, void const* )
690
     {
691
       new (m_storage.address()) value_type(expr) ;
692
       m_initialized = true ;
693
     }
694
695
    // Assigns using a form any expression implicitly convertible to the single argument
696
    // of a T's assignment operator.
697
    // Converting assignments of optional<T> from optional<U> uses this function with
698
    // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
699
    template<class Expr>
700
    void assign_expr_to_initialized ( Expr const& expr, void const* )
701
     {
702
       assign_value(expr);
703
     }
704
705
#endif
706
707
#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
708
    // BCB5.64 (and probably lower versions) workaround.
709
    //   The in-place factories are supported by means of catch-all constructors
710
    //   and assignment operators (the functions are parameterized in terms of
711
    //   an arbitrary 'Expr' type)
712
    //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
713
    //   to the 'Expr'-taking functions even though explicit overloads are present for them.
714
    //   Thus, the following overload is needed to properly handle the case when the 'lhs'
715
    //   is another optional.
716
    //
717
    // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
718
    // instead of choosing the wrong overload
719
    //
720
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
721
    // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
722
    template<class Expr>
723
    void construct ( Expr&& expr, optional_tag const* )
724
     {
725
       if ( expr.is_initialized() )
726
       {
727
         // An exception can be thrown here.
728
         // It it happens, THIS will be left uninitialized.
729
         new (m_storage.address()) value_type(boost::move(expr.get())) ;
730
         m_initialized = true ;
731
       }
732
     }
733
#else
734
    // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
735
    template<class Expr>
736
    void construct ( Expr const& expr, optional_tag const* )
737
     {
738
       if ( expr.is_initialized() )
739
       {
740
         // An exception can be thrown here.
741
         // It it happens, THIS will be left uninitialized.
742
         new (m_storage.address()) value_type(expr.get()) ;
743
         m_initialized = true ;
744
       }
745
     }
746
#endif
747
#endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
748
749
    void assign_value ( argument_type val ) { get_impl() = val; }
750
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
751
    void assign_value ( rval_reference_type val ) { get_impl() = static_cast<rval_reference_type>(val); }
752
#endif
753
754
    void destroy()
755
    {
756
      if ( m_initialized )
757
        destroy_impl() ;
758
    }
759
760
    reference_const_type get_impl() const { return m_storage.ref() ; }
761
    reference_type       get_impl()       { return m_storage.ref() ; }
762
763
    pointer_const_type get_ptr_impl() const { return m_storage.ptr_ref(); }
764
    pointer_type       get_ptr_impl()       { return m_storage.ptr_ref(); }
765
766
  private :
767
768
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900))
769
    void destroy_impl ( ) { m_storage.ptr_ref()->~T() ; m_initialized = false ; }
770
#else
771
    void destroy_impl ( ) { m_storage.ref().T::~T() ; m_initialized = false ; }
772
#endif
773
774
    bool m_initialized ;
775
    storage_type m_storage ;
776
} ;
777
778
#include <boost/optional/detail/optional_trivially_copyable_base.hpp>
779
780
// definition of metafunction is_optional_val_init_candidate
781
template <typename U>
782
struct is_optional_related
783
  : boost::conditional< boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value
784
                     || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, none_t>::value
785
                     || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, in_place_init_t>::value
786
                     || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, in_place_init_if_t>::value,
787
    boost::true_type, boost::false_type>::type
788
{};
789
790
#if !defined(BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT)
791
792
template <typename T, typename U>
793
struct is_convertible_to_T_or_factory
794
  : boost::conditional< boost::is_base_of<boost::in_place_factory_base, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value
795
                     || boost::is_base_of<boost::typed_in_place_factory_base, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value
796
                     || (boost::is_constructible<T, U&&>::value && !boost::is_same<T, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value)
797
                      , boost::true_type, boost::false_type>::type
798
{};
799
800
template <typename T, typename U>
801
struct is_optional_constructible : boost::is_constructible<T, U>
802
{};
803
804
#else
805
806
template <typename, typename>
807
struct is_convertible_to_T_or_factory : boost::true_type
808
{};
809
810
template <typename T, typename U>
811
struct is_optional_constructible : boost::true_type
812
{};
813
814
#endif // is_convertible condition
815
816
template <typename T, typename U, bool = is_optional_related<U>::value>
817
struct is_optional_val_init_candidate
818
  : boost::false_type
819
{};
820
821
template <typename T, typename U>
822
struct is_optional_val_init_candidate<T, U, false>
823
  : boost::conditional< is_convertible_to_T_or_factory<T, U>::value
824
                      , boost::true_type, boost::false_type>::type
825
{};
826
827
} // namespace optional_detail
828
829
namespace optional_config {
830
831
template <typename T>
832
struct optional_uses_direct_storage_for
833
  : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
834
                      , boost::true_type, boost::false_type>::type
835
{};
836
837
} // namespace optional_config
838
839
840
#ifndef BOOST_OPTIONAL_DETAIL_NO_DIRECT_STORAGE_SPEC
841
#  define BOOST_OPTIONAL_BASE_TYPE(T) boost::conditional< optional_config::optional_uses_direct_storage_for<T>::value, \
842
                                      optional_detail::tc_optional_base<T>, \
843
                                      optional_detail::optional_base<T> \
844
                                      >::type
845
#else
846
#  define BOOST_OPTIONAL_BASE_TYPE(T) optional_detail::optional_base<T>
847
#endif
848
849
template<class T>
850
class optional
851
  : public BOOST_OPTIONAL_BASE_TYPE(T)
852
{
853
    typedef typename BOOST_OPTIONAL_BASE_TYPE(T) base ;
854
855
  public :
856
857
    typedef optional<T> this_type ;
858
859
    typedef BOOST_DEDUCED_TYPENAME base::value_type           value_type ;
860
    typedef BOOST_DEDUCED_TYPENAME base::reference_type       reference_type ;
861
    typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
862
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
863
    typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type  rval_reference_type ;
864
    typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
865
#endif
866
    typedef BOOST_DEDUCED_TYPENAME base::pointer_type         pointer_type ;
867
    typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type   pointer_const_type ;
868
    typedef BOOST_DEDUCED_TYPENAME base::argument_type        argument_type ;
869
870
    // Creates an optional<T> uninitialized.
871
    // No-throw
872
    optional() BOOST_NOEXCEPT : base() {}
873
874
    // Creates an optional<T> uninitialized.
875
    // No-throw
876
    optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
877
878
    // Creates an optional<T> initialized with 'val'.
879
    // Can throw if T::T(T const&) does
880
    optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {}
881
882
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
883
    // Creates an optional<T> initialized with 'move(val)'.
884
    // Can throw if T::T(T &&) does
885
    optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward<T>(val))
886
      {}
887
#endif
888
889
    // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
890
    // Can throw if T::T(T const&) does
891
    optional ( bool cond, argument_type val ) : base(cond,val) {}
892
893
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
894
    /// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
895
    // Can throw if T::T(T &&) does
896
    optional ( bool cond, rval_reference_type val ) : base( cond, boost::forward<T>(val) )
897
      {}
898
#endif
899
900
    // NOTE: MSVC needs templated versions first
901
902
    // Creates a deep copy of another convertible optional<U>
903
    // Requires a valid conversion from U to T.
904
    // Can throw if T::T(U const&) does
905
    template<class U>
906
    explicit optional ( optional<U> const& rhs
907
#ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
908
                        ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U const&>, bool>::type = true
909
#endif
910
                      )
911
      :
912
      base()
913
    {
914
      if ( rhs.is_initialized() )
915
        this->construct(rhs.get());
916
    }
917
918
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
919
    // Creates a deep move of another convertible optional<U>
920
    // Requires a valid conversion from U to T.
921
    // Can throw if T::T(U&&) does
922
    template<class U>
923
    explicit optional ( optional<U> && rhs
924
#ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
925
                        ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U>, bool>::type = true
926
#endif
927
                      )
928
      :
929
      base()
930
    {
931
      if ( rhs.is_initialized() )
932
        this->construct( boost::move(rhs.get()) );
933
    }
934
#endif
935
936
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
937
    // Creates an optional<T> with an expression which can be either
938
    //  (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
939
    //  (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
940
    //  (c) Any expression implicitly convertible to the single type
941
    //      of a one-argument T's constructor.
942
    //  (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
943
    //       even though explicit overloads are present for these.
944
    // Depending on the above some T ctor is called.
945
    // Can throw if the resolved T ctor throws.
946
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
947
948
949
  template<class Expr>
950
  explicit optional ( Expr&& expr,
951
                      BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_val_init_candidate<T, Expr>, bool>::type = true
952
  )
953
    : base(boost::forward<Expr>(expr),boost::addressof(expr))
954
    {}
955
956
#else
957
    template<class Expr>
958
    explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
959
#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
960
#endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
961
962
    // Creates a deep copy of another optional<T>
963
    // Can throw if T::T(T const&) does
964
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
965
    optional ( optional const& ) = default;
966
#else
967
    optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
968
#endif
969
970
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
971
    // Creates a deep move of another optional<T>
972
    // Can throw if T::T(T&&) does
973
974
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
975
    optional ( optional && ) = default;
976
#else
977
    optional ( optional && rhs )
978
      BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
979
      : base( boost::move(rhs) )
980
    {}
981
#endif
982
983
#endif
984
985
#if BOOST_WORKAROUND(_MSC_VER, <= 1600)
986
    //  On old MSVC compilers the implicitly declared dtor is not called
987
    ~optional() {}
988
#endif
989
990
991
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
992
    // Assigns from an expression. See corresponding constructor.
993
    // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
994
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
995
996
    template<class Expr>
997
    BOOST_DEDUCED_TYPENAME boost::enable_if<optional_detail::is_optional_val_init_candidate<T, Expr>, optional&>::type
998
    operator= ( Expr&& expr )
999
      {
1000
        this->assign_expr(boost::forward<Expr>(expr),boost::addressof(expr));
1001
        return *this ;
1002
      }
1003
1004
#else
1005
    template<class Expr>
1006
    optional& operator= ( Expr const& expr )
1007
      {
1008
        this->assign_expr(expr,boost::addressof(expr));
1009
        return *this ;
1010
      }
1011
#endif // !defined  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1012
#endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
1013
1014
    // Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value)
1015
    // Requires a valid conversion from U to T.
1016
    // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
1017
    template<class U>
1018
    optional& operator= ( optional<U> const& rhs )
1019
      {
1020
        this->assign(rhs);
1021
        return *this ;
1022
      }
1023
1024
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1025
    // Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
1026
    // Requires a valid conversion from U to T.
1027
    // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
1028
    template<class U>
1029
    optional& operator= ( optional<U> && rhs )
1030
      {
1031
        this->assign(boost::move(rhs));
1032
        return *this ;
1033
      }
1034
#endif
1035
1036
    // Assigns from another optional<T> (deep-copies the rhs value)
1037
    // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
1038
    //  (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
1039
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
1040
    optional& operator= ( optional const& rhs ) = default;
1041
#else
1042
    optional& operator= ( optional const& rhs )
1043
      {
1044
        this->assign( static_cast<base const&>(rhs) ) ;
1045
        return *this ;
1046
      }
1047
#endif
1048
1049
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1050
    // Assigns from another optional<T> (deep-moves the rhs value)
1051
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
1052
    optional& operator= ( optional && ) = default;
1053
#else
1054
    optional& operator= ( optional && rhs )
1055
      BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
1056
      {
1057
        this->assign( static_cast<base &&>(rhs) ) ;
1058
        return *this ;
1059
      }
1060
#endif
1061
1062
#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1063
1064
#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
1065
1066
    // Assigns from a T (deep-moves/copies the rhs value)
1067
    template <typename T_>
1068
    BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_same<T, BOOST_DEDUCED_TYPENAME boost::decay<T_>::type>, optional&>::type
1069
    operator= ( T_&& val )
1070
      {
1071
        this->assign( boost::forward<T_>(val) ) ;
1072
        return *this ;
1073
      }
1074
1075
#else
1076
1077
    // Assigns from a T (deep-copies the rhs value)
1078
    // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
1079
    optional& operator= ( argument_type val )
1080
      {
1081
        this->assign( val ) ;
1082
        return *this ;
1083
      }
1084
1085
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1086
    // Assigns from a T (deep-moves the rhs value)
1087
    optional& operator= ( rval_reference_type val )
1088
      {
1089
        this->assign( boost::move(val) ) ;
1090
        return *this ;
1091
      }
1092
#endif
1093
1094
#endif // BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
1095
1096
    // Assigns from a "none"
1097
    // Which destroys the current value, if any, leaving this UNINITIALIZED
1098
    // No-throw (assuming T::~T() doesn't)
1099
    optional& operator= ( none_t none_ ) BOOST_NOEXCEPT
1100
      {
1101
        this->assign( none_ ) ;
1102
        return *this ;
1103
      }
1104
1105
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1106
    // Constructs in-place
1107
    // upon exception *this is always uninitialized
1108
    template<class... Args>
1109
    void emplace ( Args&&... args )
1110
    {
1111
      this->emplace_assign( boost::forward<Args>(args)... );
1112
    }
1113
1114
    template<class... Args>
1115
    explicit optional ( in_place_init_t, Args&&... args )
1116
    : base( in_place_init, boost::forward<Args>(args)... )
1117
    {}
1118
1119
    template<class... Args>
1120
    explicit optional ( in_place_init_if_t, bool cond, Args&&... args )
1121
    : base( in_place_init_if, cond, boost::forward<Args>(args)... )
1122
    {}
1123
1124
#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
1125
    template<class Arg>
1126
    void emplace ( Arg&& arg )
1127
     {
1128
       this->emplace_assign( boost::forward<Arg>(arg) );
1129
     }
1130
1131
    void emplace ()
1132
     {
1133
       this->emplace_assign();
1134
     }
1135
1136
    template<class Args>
1137
    explicit optional ( in_place_init_t, Args&& args )
1138
    : base( in_place_init, boost::forward<Args>(args) )
1139
    {}
1140
1141
    explicit optional ( in_place_init_t )
1142
    : base( in_place_init )
1143
    {}
1144
1145
    template<class Args>
1146
    explicit optional ( in_place_init_if_t, bool cond, Args&& args )
1147
    : base( in_place_init_if, cond, boost::forward<Args>(args) )
1148
    {}
1149
1150
    explicit optional ( in_place_init_if_t, bool cond )
1151
    : base( in_place_init_if, cond )
1152
    {}
1153
#else
1154
    template<class Arg>
1155
    void emplace ( const Arg& arg )
1156
     {
1157
       this->emplace_assign( arg );
1158
     }
1159
1160
    template<class Arg>
1161
    void emplace ( Arg& arg )
1162
     {
1163
       this->emplace_assign( arg );
1164
     }
1165
1166
    void emplace ()
1167
     {
1168
       this->emplace_assign();
1169
     }
1170
1171
    template<class Arg>
1172
    explicit optional ( in_place_init_t, const Arg& arg )
1173
    : base( in_place_init, arg )
1174
    {}
1175
1176
    template<class Arg>
1177
    explicit optional ( in_place_init_t, Arg& arg )
1178
    : base( in_place_init, arg )
1179
    {}
1180
1181
    explicit optional ( in_place_init_t )
1182
    : base( in_place_init )
1183
    {}
1184
1185
    template<class Arg>
1186
    explicit optional ( in_place_init_if_t, bool cond, const Arg& arg )
1187
    : base( in_place_init_if, cond, arg )
1188
    {}
1189
1190
    template<class Arg>
1191
    explicit optional ( in_place_init_if_t, bool cond, Arg& arg )
1192
    : base( in_place_init_if, cond, arg )
1193
    {}
1194
1195
    explicit optional ( in_place_init_if_t, bool cond )
1196
    : base( in_place_init_if, cond )
1197
    {}
1198
#endif
1199
1200
    void swap( optional & arg )
1201
      BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
1202
      {
1203
        // allow for Koenig lookup
1204
        boost::swap(*this, arg);
1205
      }
1206
1207
1208
    // Returns a reference to the value if this is initialized, otherwise,
1209
    // the behaviour is UNDEFINED
1210
    // No-throw
1211
    reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
1212
    reference_type       get()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
1213
1214
    // Returns a copy of the value if this is initialized, 'v' otherwise
1215
    reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
1216
    reference_type       get_value_or ( reference_type       v )       { return this->is_initialized() ? get() : v ; }
1217
1218
    // Returns a pointer to the value if this is initialized, otherwise,
1219
    // the behaviour is UNDEFINED
1220
    // No-throw
1221
    pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
1222
    pointer_type       operator->()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
1223
1224
    // Returns a reference to the value if this is initialized, otherwise,
1225
    // the behaviour is UNDEFINED
1226
    // No-throw
1227
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
1228
    reference_const_type operator *() const& { return this->get() ; }
1229
    reference_type       operator *() &      { return this->get() ; }
1230
    reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; }
1231
#else
1232
    reference_const_type operator *() const { return this->get() ; }
1233
    reference_type       operator *()       { return this->get() ; }
1234
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
1235
1236
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
1237
    reference_const_type value() const&
1238
      {
1239
        if (this->is_initialized())
1240
          return this->get() ;
1241
        else
1242
          throw_exception(bad_optional_access());
1243
      }
1244
1245
    reference_type value() &
1246
      {
1247
        if (this->is_initialized())
1248
          return this->get() ;
1249
        else
1250
          throw_exception(bad_optional_access());
1251
      }
1252
1253
    reference_type_of_temporary_wrapper value() &&
1254
      {
1255
        if (this->is_initialized())
1256
          return boost::move(this->get()) ;
1257
        else
1258
          throw_exception(bad_optional_access());
1259
      }
1260
1261
#else
1262
    reference_const_type value() const
1263
      {
1264
        if (this->is_initialized())
1265
          return this->get() ;
1266
        else
1267
          throw_exception(bad_optional_access());
1268
      }
1269
1270
    reference_type value()
1271
      {
1272
        if (this->is_initialized())
1273
          return this->get() ;
1274
        else
1275
          throw_exception(bad_optional_access());
1276
      }
1277
#endif
1278
1279
1280
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
1281
    template <class U>
1282
    value_type value_or ( U&& v ) const&
1283
      {
1284
        if (this->is_initialized())
1285
          return get();
1286
        else
1287
          return boost::forward<U>(v);
1288
      }
1289
1290
    template <class U>
1291
    value_type value_or ( U&& v ) &&
1292
      {
1293
        if (this->is_initialized())
1294
          return boost::move(get());
1295
        else
1296
          return boost::forward<U>(v);
1297
      }
1298
#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1299
    template <class U>
1300
    value_type value_or ( U&& v ) const
1301
      {
1302
        if (this->is_initialized())
1303
          return get();
1304
        else
1305
          return boost::forward<U>(v);
1306
      }
1307
#else
1308
    template <class U>
1309
    value_type value_or ( U const& v ) const
1310
      {
1311
        if (this->is_initialized())
1312
          return get();
1313
        else
1314
          return v;
1315
      }
1316
1317
    template <class U>
1318
    value_type value_or ( U& v ) const
1319
      {
1320
        if (this->is_initialized())
1321
          return get();
1322
        else
1323
          return v;
1324
      }
1325
#endif
1326
1327
1328
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
1329
    template <typename F>
1330
    value_type value_or_eval ( F f ) const&
1331
      {
1332
        if (this->is_initialized())
1333
          return get();
1334
        else
1335
          return f();
1336
      }
1337
1338
    template <typename F>
1339
    value_type value_or_eval ( F f ) &&
1340
      {
1341
        if (this->is_initialized())
1342
          return boost::move(get());
1343
        else
1344
          return f();
1345
      }
1346
1347
    template <typename F>
1348
    optional<typename boost::result_of<F(reference_type)>::type> map(F f) &
1349
      {
1350
        if (this->has_value())
1351
          return f(get());
1352
        else
1353
          return none;
1354
      }
1355
1356
    template <typename F>
1357
    optional<typename boost::result_of<F(reference_const_type)>::type> map(F f) const&
1358
      {
1359
        if (this->has_value())
1360
          return f(get());
1361
        else
1362
          return none;
1363
      }
1364
1365
    template <typename F>
1366
    optional<typename boost::result_of<F(reference_type_of_temporary_wrapper)>::type> map(F f) &&
1367
      {
1368
        if (this->has_value())
1369
          return f(boost::move(this->get()));
1370
        else
1371
          return none;
1372
      }
1373
1374
    template <typename F>
1375
    optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_type)>::type>::type> flat_map(F f) &
1376
      {
1377
        if (this->has_value())
1378
          return f(get());
1379
        else
1380
          return none;
1381
      }
1382
1383
    template <typename F>
1384
    optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_const_type)>::type>::type> flat_map(F f) const&
1385
      {
1386
        if (this->has_value())
1387
          return f(get());
1388
        else
1389
          return none;
1390
      }
1391
1392
    template <typename F>
1393
    optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_type_of_temporary_wrapper)>::type>::type> flat_map(F f) &&
1394
      {
1395
        if (this->has_value())
1396
          return f(boost::move(get()));
1397
        else
1398
          return none;
1399
      }
1400
1401
#else
1402
    template <typename F>
1403
    value_type value_or_eval ( F f ) const
1404
      {
1405
        if (this->is_initialized())
1406
          return get();
1407
        else
1408
          return f();
1409
      }
1410
1411
    template <typename F>
1412
    optional<typename boost::result_of<F(reference_type)>::type> map(F f)
1413
      {
1414
        if (this->has_value())
1415
          return f(get());
1416
        else
1417
          return none;
1418
      }
1419
1420
    template <typename F>
1421
    optional<typename boost::result_of<F(reference_const_type)>::type> map(F f) const
1422
      {
1423
        if (this->has_value())
1424
          return f(get());
1425
        else
1426
          return none;
1427
      }
1428
1429
    template <typename F>
1430
    optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_type)>::type>::type> flat_map(F f)
1431
      {
1432
        if (this->has_value())
1433
          return f(get());
1434
        else
1435
          return none;
1436
      }
1437
1438
    template <typename F>
1439
    optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_const_type)>::type>::type> flat_map(F f) const
1440
      {
1441
        if (this->has_value())
1442
          return f(get());
1443
        else
1444
          return none;
1445
      }
1446
1447
#endif
1448
1449
    bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; }
1450
1451
    bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
1452
1453
    BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
1454
} ;
1455
1456
} // namespace boost
1457
1458
#endif // BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL
1459
1460
namespace boost {
1461
1462
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1463
template<class T>
1464
class optional<T&&>
1465
{
1466
  BOOST_STATIC_ASSERT_MSG(sizeof(T) == 0, "Optional rvalue references are illegal.");
1467
} ;
1468
#endif
1469
1470
} // namespace boost
1471
1472
#ifndef BOOST_OPTIONAL_CONFIG_DONT_SPECIALIZE_OPTIONAL_REFS
1473
# include <boost/optional/detail/optional_reference_spec.hpp>
1474
#endif
1475
1476
namespace boost {
1477
1478
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1479
1480
template<class T>
1481
inline
1482
optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( T && v  )
1483
{
1484
  return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(boost::forward<T>(v));
1485
}
1486
1487
// Returns optional<T>(cond,v)
1488
template<class T>
1489
inline
1490
optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( bool cond, T && v )
1491
{
1492
  return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(cond,boost::forward<T>(v));
1493
}
1494
1495
#else
1496
1497
// Returns optional<T>(v)
1498
template<class T>
1499
inline
1500
optional<T> make_optional ( T const& v  )
1501
{
1502
  return optional<T>(v);
1503
}
1504
1505
// Returns optional<T>(cond,v)
1506
template<class T>
1507
inline
1508
optional<T> make_optional ( bool cond, T const& v )
1509
{
1510
  return optional<T>(cond,v);
1511
}
1512
1513
#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1514
1515
// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
1516
// No-throw
1517
template<class T>
1518
inline
1519
BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
1520
get ( optional<T> const& opt )
1521
{
1522
  return opt.get() ;
1523
}
1524
1525
template<class T>
1526
inline
1527
BOOST_DEDUCED_TYPENAME optional<T>::reference_type
1528
get ( optional<T>& opt )
1529
{
1530
  return opt.get() ;
1531
}
1532
1533
// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
1534
// No-throw
1535
template<class T>
1536
inline
1537
BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
1538
get ( optional<T> const* opt )
1539
{
1540
  return opt->get_ptr() ;
1541
}
1542
1543
template<class T>
1544
inline
1545
BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
1546
get ( optional<T>* opt )
1547
{
1548
  return opt->get_ptr() ;
1549
}
1550
1551
// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
1552
// No-throw
1553
template<class T>
1554
inline
1555
BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
1556
get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
1557
{
1558
  return opt.get_value_or(v) ;
1559
}
1560
1561
template<class T>
1562
inline
1563
BOOST_DEDUCED_TYPENAME optional<T>::reference_type
1564
get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
1565
{
1566
  return opt.get_value_or(v) ;
1567
}
1568
1569
// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
1570
// No-throw
1571
template<class T>
1572
inline
1573
BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
1574
get_pointer ( optional<T> const& opt )
1575
{
1576
  return opt.get_ptr() ;
1577
}
1578
1579
template<class T>
1580
inline
1581
BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
1582
get_pointer ( optional<T>& opt )
1583
{
1584
  return opt.get_ptr() ;
1585
}
1586
1587
} // namespace boost
1588
1589
namespace boost {
1590
1591
// The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header.
1592
template<class CharType, class CharTrait>
1593
std::basic_ostream<CharType, CharTrait>&
1594
operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optional_tag const&)
1595
{
1596
  BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output boost::optional, include header <boost/optional/optional_io.hpp>");
1597
  return os;
1598
}
1599
1600
} // namespace boost
1601
1602
#include <boost/optional/detail/optional_relops.hpp>
1603
#include <boost/optional/detail/optional_swap.hpp>
1604
1605
#endif // header guard
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/preprocessor/cat.hpp
Line
Count
Source
1
# /* Copyright (C) 2001
2
#  * Housemarque Oy
3
#  * http://www.housemarque.com
4
#  *
5
#  * Distributed under the Boost Software License, Version 1.0. (See
6
#  * accompanying file LICENSE_1_0.txt or copy at
7
#  * http://www.boost.org/LICENSE_1_0.txt)
8
#  */
9
#
10
# /* Revised by Paul Mensonides (2002) */
11
#
12
# /* See http://www.boost.org for most recent version. */
13
#
14
# ifndef BOOST_PREPROCESSOR_CAT_HPP
15
# define BOOST_PREPROCESSOR_CAT_HPP
16
#
17
# include <boost/preprocessor/config/config.hpp>
18
#
19
# /* BOOST_PP_CAT */
20
#
21
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
22
360
#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
23
# else
24
#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_OO((a, b))
25
#    define BOOST_PP_CAT_OO(par) BOOST_PP_CAT_I ## par
26
# endif
27
#
28
# if (~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1700)
29
360
#    define BOOST_PP_CAT_I(a, b) a ## b
30
# else
31
#    define BOOST_PP_CAT_I(a, b) BOOST_PP_CAT_II(~, a ## b)
32
#    define BOOST_PP_CAT_II(p, res) res
33
# endif
34
#
35
# endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/preprocessor/repetition/enum.hpp
Line
Count
Source
1
# /* Copyright (C) 2001
2
#  * Housemarque Oy
3
#  * http://www.housemarque.com
4
#  *
5
#  * Distributed under the Boost Software License, Version 1.0. (See
6
#  * accompanying file LICENSE_1_0.txt or copy at
7
#  * http://www.boost.org/LICENSE_1_0.txt)
8
#  */
9
#
10
# /* Revised by Paul Mensonides (2002) */
11
#
12
# /* See http://www.boost.org for most recent version. */
13
#
14
# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_HPP
15
# define BOOST_PREPROCESSOR_REPETITION_ENUM_HPP
16
#
17
# include <boost/preprocessor/cat.hpp>
18
# include <boost/preprocessor/config/config.hpp>
19
# include <boost/preprocessor/debug/error.hpp>
20
# include <boost/preprocessor/detail/auto_rec.hpp>
21
# include <boost/preprocessor/punctuation/comma_if.hpp>
22
# include <boost/preprocessor/repetition/repeat.hpp>
23
# include <boost/preprocessor/tuple/elem.hpp>
24
# include <boost/preprocessor/tuple/rem.hpp>
25
#
26
# /* BOOST_PP_ENUM */
27
#
28
# if 0
29
#    define BOOST_PP_ENUM(count, macro, data)
30
# endif
31
#
32
120
# define BOOST_PP_ENUM BOOST_PP_CAT(BOOST_PP_ENUM_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
33
#
34
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
35
240
#    define BOOST_PP_ENUM_1(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_M_1, (m, d))
36
#    define BOOST_PP_ENUM_2(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_M_2, (m, d))
37
#    define BOOST_PP_ENUM_3(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_M_3, (m, d))
38
# else
39
#    define BOOST_PP_ENUM_1(c, m, d) BOOST_PP_ENUM_1_I(c, m, d)
40
#    define BOOST_PP_ENUM_2(c, m, d) BOOST_PP_ENUM_2_I(c, m, d)
41
#    define BOOST_PP_ENUM_3(c, m, d) BOOST_PP_ENUM_3_I(c, m, d)
42
#    define BOOST_PP_ENUM_1_I(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_M_1, (m, d))
43
#    define BOOST_PP_ENUM_2_I(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_M_2, (m, d))
44
#    define BOOST_PP_ENUM_3_I(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_M_3, (m, d))
45
# endif
46
#
47
# define BOOST_PP_ENUM_4(c, m, d) BOOST_PP_ERROR(0x0003)
48
#
49
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
50
240
#    define BOOST_PP_ENUM_M_1(z, n, md) BOOST_PP_ENUM_M_1_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
51
#    define BOOST_PP_ENUM_M_2(z, n, md) BOOST_PP_ENUM_M_2_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
52
#    define BOOST_PP_ENUM_M_3(z, n, md) BOOST_PP_ENUM_M_3_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
53
240
#    define BOOST_PP_ENUM_M_1_IM(z, n, im) BOOST_PP_ENUM_M_1_I(z, n, im)
54
#    define BOOST_PP_ENUM_M_2_IM(z, n, im) BOOST_PP_ENUM_M_2_I(z, n, im)
55
#    define BOOST_PP_ENUM_M_3_IM(z, n, im) BOOST_PP_ENUM_M_3_I(z, n, im)
56
# else
57
#    define BOOST_PP_ENUM_M_1(z, n, md) BOOST_PP_ENUM_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
58
#    define BOOST_PP_ENUM_M_2(z, n, md) BOOST_PP_ENUM_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
59
#    define BOOST_PP_ENUM_M_3(z, n, md) BOOST_PP_ENUM_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
60
# endif
61
#
62
240
# define BOOST_PP_ENUM_M_1_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d)
63
# define BOOST_PP_ENUM_M_2_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d)
64
# define BOOST_PP_ENUM_M_3_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d)
65
#
66
# endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/preprocessor/repetition/limits/repeat_256.hpp
Line
Count
Source
1
# /* Copyright (C) 2001
2
#  * Housemarque Oy
3
#  * http://www.housemarque.com
4
#  *
5
#  * Distributed under the Boost Software License, Version 1.0. (See
6
#  * accompanying file LICENSE_1_0.txt or copy at
7
#  * http://www.boost.org/LICENSE_1_0.txt)
8
#  */
9
#
10
# /* Revised by Paul Mensonides (2002) */
11
#
12
# /* See http://www.boost.org for most recent version. */
13
#
14
# ifndef BOOST_PREPROCESSOR_REPETITION_REPEAT_256_HPP
15
# define BOOST_PREPROCESSOR_REPETITION_REPEAT_256_HPP
16
#
17
# define BOOST_PP_REPEAT_1_0(m, d)
18
120
# define BOOST_PP_REPEAT_1_1(m, d) m(2, 0, d)
19
120
# define BOOST_PP_REPEAT_1_2(m, d) BOOST_PP_REPEAT_1_1(m, d) m(2, 1, d)
20
# define BOOST_PP_REPEAT_1_3(m, d) BOOST_PP_REPEAT_1_2(m, d) m(2, 2, d)
21
# define BOOST_PP_REPEAT_1_4(m, d) BOOST_PP_REPEAT_1_3(m, d) m(2, 3, d)
22
# define BOOST_PP_REPEAT_1_5(m, d) BOOST_PP_REPEAT_1_4(m, d) m(2, 4, d)
23
# define BOOST_PP_REPEAT_1_6(m, d) BOOST_PP_REPEAT_1_5(m, d) m(2, 5, d)
24
# define BOOST_PP_REPEAT_1_7(m, d) BOOST_PP_REPEAT_1_6(m, d) m(2, 6, d)
25
# define BOOST_PP_REPEAT_1_8(m, d) BOOST_PP_REPEAT_1_7(m, d) m(2, 7, d)
26
# define BOOST_PP_REPEAT_1_9(m, d) BOOST_PP_REPEAT_1_8(m, d) m(2, 8, d)
27
# define BOOST_PP_REPEAT_1_10(m, d) BOOST_PP_REPEAT_1_9(m, d) m(2, 9, d)
28
# define BOOST_PP_REPEAT_1_11(m, d) BOOST_PP_REPEAT_1_10(m, d) m(2, 10, d)
29
# define BOOST_PP_REPEAT_1_12(m, d) BOOST_PP_REPEAT_1_11(m, d) m(2, 11, d)
30
# define BOOST_PP_REPEAT_1_13(m, d) BOOST_PP_REPEAT_1_12(m, d) m(2, 12, d)
31
# define BOOST_PP_REPEAT_1_14(m, d) BOOST_PP_REPEAT_1_13(m, d) m(2, 13, d)
32
# define BOOST_PP_REPEAT_1_15(m, d) BOOST_PP_REPEAT_1_14(m, d) m(2, 14, d)
33
# define BOOST_PP_REPEAT_1_16(m, d) BOOST_PP_REPEAT_1_15(m, d) m(2, 15, d)
34
# define BOOST_PP_REPEAT_1_17(m, d) BOOST_PP_REPEAT_1_16(m, d) m(2, 16, d)
35
# define BOOST_PP_REPEAT_1_18(m, d) BOOST_PP_REPEAT_1_17(m, d) m(2, 17, d)
36
# define BOOST_PP_REPEAT_1_19(m, d) BOOST_PP_REPEAT_1_18(m, d) m(2, 18, d)
37
# define BOOST_PP_REPEAT_1_20(m, d) BOOST_PP_REPEAT_1_19(m, d) m(2, 19, d)
38
# define BOOST_PP_REPEAT_1_21(m, d) BOOST_PP_REPEAT_1_20(m, d) m(2, 20, d)
39
# define BOOST_PP_REPEAT_1_22(m, d) BOOST_PP_REPEAT_1_21(m, d) m(2, 21, d)
40
# define BOOST_PP_REPEAT_1_23(m, d) BOOST_PP_REPEAT_1_22(m, d) m(2, 22, d)
41
# define BOOST_PP_REPEAT_1_24(m, d) BOOST_PP_REPEAT_1_23(m, d) m(2, 23, d)
42
# define BOOST_PP_REPEAT_1_25(m, d) BOOST_PP_REPEAT_1_24(m, d) m(2, 24, d)
43
# define BOOST_PP_REPEAT_1_26(m, d) BOOST_PP_REPEAT_1_25(m, d) m(2, 25, d)
44
# define BOOST_PP_REPEAT_1_27(m, d) BOOST_PP_REPEAT_1_26(m, d) m(2, 26, d)
45
# define BOOST_PP_REPEAT_1_28(m, d) BOOST_PP_REPEAT_1_27(m, d) m(2, 27, d)
46
# define BOOST_PP_REPEAT_1_29(m, d) BOOST_PP_REPEAT_1_28(m, d) m(2, 28, d)
47
# define BOOST_PP_REPEAT_1_30(m, d) BOOST_PP_REPEAT_1_29(m, d) m(2, 29, d)
48
# define BOOST_PP_REPEAT_1_31(m, d) BOOST_PP_REPEAT_1_30(m, d) m(2, 30, d)
49
# define BOOST_PP_REPEAT_1_32(m, d) BOOST_PP_REPEAT_1_31(m, d) m(2, 31, d)
50
# define BOOST_PP_REPEAT_1_33(m, d) BOOST_PP_REPEAT_1_32(m, d) m(2, 32, d)
51
# define BOOST_PP_REPEAT_1_34(m, d) BOOST_PP_REPEAT_1_33(m, d) m(2, 33, d)
52
# define BOOST_PP_REPEAT_1_35(m, d) BOOST_PP_REPEAT_1_34(m, d) m(2, 34, d)
53
# define BOOST_PP_REPEAT_1_36(m, d) BOOST_PP_REPEAT_1_35(m, d) m(2, 35, d)
54
# define BOOST_PP_REPEAT_1_37(m, d) BOOST_PP_REPEAT_1_36(m, d) m(2, 36, d)
55
# define BOOST_PP_REPEAT_1_38(m, d) BOOST_PP_REPEAT_1_37(m, d) m(2, 37, d)
56
# define BOOST_PP_REPEAT_1_39(m, d) BOOST_PP_REPEAT_1_38(m, d) m(2, 38, d)
57
# define BOOST_PP_REPEAT_1_40(m, d) BOOST_PP_REPEAT_1_39(m, d) m(2, 39, d)
58
# define BOOST_PP_REPEAT_1_41(m, d) BOOST_PP_REPEAT_1_40(m, d) m(2, 40, d)
59
# define BOOST_PP_REPEAT_1_42(m, d) BOOST_PP_REPEAT_1_41(m, d) m(2, 41, d)
60
# define BOOST_PP_REPEAT_1_43(m, d) BOOST_PP_REPEAT_1_42(m, d) m(2, 42, d)
61
# define BOOST_PP_REPEAT_1_44(m, d) BOOST_PP_REPEAT_1_43(m, d) m(2, 43, d)
62
# define BOOST_PP_REPEAT_1_45(m, d) BOOST_PP_REPEAT_1_44(m, d) m(2, 44, d)
63
# define BOOST_PP_REPEAT_1_46(m, d) BOOST_PP_REPEAT_1_45(m, d) m(2, 45, d)
64
# define BOOST_PP_REPEAT_1_47(m, d) BOOST_PP_REPEAT_1_46(m, d) m(2, 46, d)
65
# define BOOST_PP_REPEAT_1_48(m, d) BOOST_PP_REPEAT_1_47(m, d) m(2, 47, d)
66
# define BOOST_PP_REPEAT_1_49(m, d) BOOST_PP_REPEAT_1_48(m, d) m(2, 48, d)
67
# define BOOST_PP_REPEAT_1_50(m, d) BOOST_PP_REPEAT_1_49(m, d) m(2, 49, d)
68
# define BOOST_PP_REPEAT_1_51(m, d) BOOST_PP_REPEAT_1_50(m, d) m(2, 50, d)
69
# define BOOST_PP_REPEAT_1_52(m, d) BOOST_PP_REPEAT_1_51(m, d) m(2, 51, d)
70
# define BOOST_PP_REPEAT_1_53(m, d) BOOST_PP_REPEAT_1_52(m, d) m(2, 52, d)
71
# define BOOST_PP_REPEAT_1_54(m, d) BOOST_PP_REPEAT_1_53(m, d) m(2, 53, d)
72
# define BOOST_PP_REPEAT_1_55(m, d) BOOST_PP_REPEAT_1_54(m, d) m(2, 54, d)
73
# define BOOST_PP_REPEAT_1_56(m, d) BOOST_PP_REPEAT_1_55(m, d) m(2, 55, d)
74
# define BOOST_PP_REPEAT_1_57(m, d) BOOST_PP_REPEAT_1_56(m, d) m(2, 56, d)
75
# define BOOST_PP_REPEAT_1_58(m, d) BOOST_PP_REPEAT_1_57(m, d) m(2, 57, d)
76
# define BOOST_PP_REPEAT_1_59(m, d) BOOST_PP_REPEAT_1_58(m, d) m(2, 58, d)
77
# define BOOST_PP_REPEAT_1_60(m, d) BOOST_PP_REPEAT_1_59(m, d) m(2, 59, d)
78
# define BOOST_PP_REPEAT_1_61(m, d) BOOST_PP_REPEAT_1_60(m, d) m(2, 60, d)
79
# define BOOST_PP_REPEAT_1_62(m, d) BOOST_PP_REPEAT_1_61(m, d) m(2, 61, d)
80
# define BOOST_PP_REPEAT_1_63(m, d) BOOST_PP_REPEAT_1_62(m, d) m(2, 62, d)
81
# define BOOST_PP_REPEAT_1_64(m, d) BOOST_PP_REPEAT_1_63(m, d) m(2, 63, d)
82
# define BOOST_PP_REPEAT_1_65(m, d) BOOST_PP_REPEAT_1_64(m, d) m(2, 64, d)
83
# define BOOST_PP_REPEAT_1_66(m, d) BOOST_PP_REPEAT_1_65(m, d) m(2, 65, d)
84
# define BOOST_PP_REPEAT_1_67(m, d) BOOST_PP_REPEAT_1_66(m, d) m(2, 66, d)
85
# define BOOST_PP_REPEAT_1_68(m, d) BOOST_PP_REPEAT_1_67(m, d) m(2, 67, d)
86
# define BOOST_PP_REPEAT_1_69(m, d) BOOST_PP_REPEAT_1_68(m, d) m(2, 68, d)
87
# define BOOST_PP_REPEAT_1_70(m, d) BOOST_PP_REPEAT_1_69(m, d) m(2, 69, d)
88
# define BOOST_PP_REPEAT_1_71(m, d) BOOST_PP_REPEAT_1_70(m, d) m(2, 70, d)
89
# define BOOST_PP_REPEAT_1_72(m, d) BOOST_PP_REPEAT_1_71(m, d) m(2, 71, d)
90
# define BOOST_PP_REPEAT_1_73(m, d) BOOST_PP_REPEAT_1_72(m, d) m(2, 72, d)
91
# define BOOST_PP_REPEAT_1_74(m, d) BOOST_PP_REPEAT_1_73(m, d) m(2, 73, d)
92
# define BOOST_PP_REPEAT_1_75(m, d) BOOST_PP_REPEAT_1_74(m, d) m(2, 74, d)
93
# define BOOST_PP_REPEAT_1_76(m, d) BOOST_PP_REPEAT_1_75(m, d) m(2, 75, d)
94
# define BOOST_PP_REPEAT_1_77(m, d) BOOST_PP_REPEAT_1_76(m, d) m(2, 76, d)
95
# define BOOST_PP_REPEAT_1_78(m, d) BOOST_PP_REPEAT_1_77(m, d) m(2, 77, d)
96
# define BOOST_PP_REPEAT_1_79(m, d) BOOST_PP_REPEAT_1_78(m, d) m(2, 78, d)
97
# define BOOST_PP_REPEAT_1_80(m, d) BOOST_PP_REPEAT_1_79(m, d) m(2, 79, d)
98
# define BOOST_PP_REPEAT_1_81(m, d) BOOST_PP_REPEAT_1_80(m, d) m(2, 80, d)
99
# define BOOST_PP_REPEAT_1_82(m, d) BOOST_PP_REPEAT_1_81(m, d) m(2, 81, d)
100
# define BOOST_PP_REPEAT_1_83(m, d) BOOST_PP_REPEAT_1_82(m, d) m(2, 82, d)
101
# define BOOST_PP_REPEAT_1_84(m, d) BOOST_PP_REPEAT_1_83(m, d) m(2, 83, d)
102
# define BOOST_PP_REPEAT_1_85(m, d) BOOST_PP_REPEAT_1_84(m, d) m(2, 84, d)
103
# define BOOST_PP_REPEAT_1_86(m, d) BOOST_PP_REPEAT_1_85(m, d) m(2, 85, d)
104
# define BOOST_PP_REPEAT_1_87(m, d) BOOST_PP_REPEAT_1_86(m, d) m(2, 86, d)
105
# define BOOST_PP_REPEAT_1_88(m, d) BOOST_PP_REPEAT_1_87(m, d) m(2, 87, d)
106
# define BOOST_PP_REPEAT_1_89(m, d) BOOST_PP_REPEAT_1_88(m, d) m(2, 88, d)
107
# define BOOST_PP_REPEAT_1_90(m, d) BOOST_PP_REPEAT_1_89(m, d) m(2, 89, d)
108
# define BOOST_PP_REPEAT_1_91(m, d) BOOST_PP_REPEAT_1_90(m, d) m(2, 90, d)
109
# define BOOST_PP_REPEAT_1_92(m, d) BOOST_PP_REPEAT_1_91(m, d) m(2, 91, d)
110
# define BOOST_PP_REPEAT_1_93(m, d) BOOST_PP_REPEAT_1_92(m, d) m(2, 92, d)
111
# define BOOST_PP_REPEAT_1_94(m, d) BOOST_PP_REPEAT_1_93(m, d) m(2, 93, d)
112
# define BOOST_PP_REPEAT_1_95(m, d) BOOST_PP_REPEAT_1_94(m, d) m(2, 94, d)
113
# define BOOST_PP_REPEAT_1_96(m, d) BOOST_PP_REPEAT_1_95(m, d) m(2, 95, d)
114
# define BOOST_PP_REPEAT_1_97(m, d) BOOST_PP_REPEAT_1_96(m, d) m(2, 96, d)
115
# define BOOST_PP_REPEAT_1_98(m, d) BOOST_PP_REPEAT_1_97(m, d) m(2, 97, d)
116
# define BOOST_PP_REPEAT_1_99(m, d) BOOST_PP_REPEAT_1_98(m, d) m(2, 98, d)
117
# define BOOST_PP_REPEAT_1_100(m, d) BOOST_PP_REPEAT_1_99(m, d) m(2, 99, d)
118
# define BOOST_PP_REPEAT_1_101(m, d) BOOST_PP_REPEAT_1_100(m, d) m(2, 100, d)
119
# define BOOST_PP_REPEAT_1_102(m, d) BOOST_PP_REPEAT_1_101(m, d) m(2, 101, d)
120
# define BOOST_PP_REPEAT_1_103(m, d) BOOST_PP_REPEAT_1_102(m, d) m(2, 102, d)
121
# define BOOST_PP_REPEAT_1_104(m, d) BOOST_PP_REPEAT_1_103(m, d) m(2, 103, d)
122
# define BOOST_PP_REPEAT_1_105(m, d) BOOST_PP_REPEAT_1_104(m, d) m(2, 104, d)
123
# define BOOST_PP_REPEAT_1_106(m, d) BOOST_PP_REPEAT_1_105(m, d) m(2, 105, d)
124
# define BOOST_PP_REPEAT_1_107(m, d) BOOST_PP_REPEAT_1_106(m, d) m(2, 106, d)
125
# define BOOST_PP_REPEAT_1_108(m, d) BOOST_PP_REPEAT_1_107(m, d) m(2, 107, d)
126
# define BOOST_PP_REPEAT_1_109(m, d) BOOST_PP_REPEAT_1_108(m, d) m(2, 108, d)
127
# define BOOST_PP_REPEAT_1_110(m, d) BOOST_PP_REPEAT_1_109(m, d) m(2, 109, d)
128
# define BOOST_PP_REPEAT_1_111(m, d) BOOST_PP_REPEAT_1_110(m, d) m(2, 110, d)
129
# define BOOST_PP_REPEAT_1_112(m, d) BOOST_PP_REPEAT_1_111(m, d) m(2, 111, d)
130
# define BOOST_PP_REPEAT_1_113(m, d) BOOST_PP_REPEAT_1_112(m, d) m(2, 112, d)
131
# define BOOST_PP_REPEAT_1_114(m, d) BOOST_PP_REPEAT_1_113(m, d) m(2, 113, d)
132
# define BOOST_PP_REPEAT_1_115(m, d) BOOST_PP_REPEAT_1_114(m, d) m(2, 114, d)
133
# define BOOST_PP_REPEAT_1_116(m, d) BOOST_PP_REPEAT_1_115(m, d) m(2, 115, d)
134
# define BOOST_PP_REPEAT_1_117(m, d) BOOST_PP_REPEAT_1_116(m, d) m(2, 116, d)
135
# define BOOST_PP_REPEAT_1_118(m, d) BOOST_PP_REPEAT_1_117(m, d) m(2, 117, d)
136
# define BOOST_PP_REPEAT_1_119(m, d) BOOST_PP_REPEAT_1_118(m, d) m(2, 118, d)
137
# define BOOST_PP_REPEAT_1_120(m, d) BOOST_PP_REPEAT_1_119(m, d) m(2, 119, d)
138
# define BOOST_PP_REPEAT_1_121(m, d) BOOST_PP_REPEAT_1_120(m, d) m(2, 120, d)
139
# define BOOST_PP_REPEAT_1_122(m, d) BOOST_PP_REPEAT_1_121(m, d) m(2, 121, d)
140
# define BOOST_PP_REPEAT_1_123(m, d) BOOST_PP_REPEAT_1_122(m, d) m(2, 122, d)
141
# define BOOST_PP_REPEAT_1_124(m, d) BOOST_PP_REPEAT_1_123(m, d) m(2, 123, d)
142
# define BOOST_PP_REPEAT_1_125(m, d) BOOST_PP_REPEAT_1_124(m, d) m(2, 124, d)
143
# define BOOST_PP_REPEAT_1_126(m, d) BOOST_PP_REPEAT_1_125(m, d) m(2, 125, d)
144
# define BOOST_PP_REPEAT_1_127(m, d) BOOST_PP_REPEAT_1_126(m, d) m(2, 126, d)
145
# define BOOST_PP_REPEAT_1_128(m, d) BOOST_PP_REPEAT_1_127(m, d) m(2, 127, d)
146
# define BOOST_PP_REPEAT_1_129(m, d) BOOST_PP_REPEAT_1_128(m, d) m(2, 128, d)
147
# define BOOST_PP_REPEAT_1_130(m, d) BOOST_PP_REPEAT_1_129(m, d) m(2, 129, d)
148
# define BOOST_PP_REPEAT_1_131(m, d) BOOST_PP_REPEAT_1_130(m, d) m(2, 130, d)
149
# define BOOST_PP_REPEAT_1_132(m, d) BOOST_PP_REPEAT_1_131(m, d) m(2, 131, d)
150
# define BOOST_PP_REPEAT_1_133(m, d) BOOST_PP_REPEAT_1_132(m, d) m(2, 132, d)
151
# define BOOST_PP_REPEAT_1_134(m, d) BOOST_PP_REPEAT_1_133(m, d) m(2, 133, d)
152
# define BOOST_PP_REPEAT_1_135(m, d) BOOST_PP_REPEAT_1_134(m, d) m(2, 134, d)
153
# define BOOST_PP_REPEAT_1_136(m, d) BOOST_PP_REPEAT_1_135(m, d) m(2, 135, d)
154
# define BOOST_PP_REPEAT_1_137(m, d) BOOST_PP_REPEAT_1_136(m, d) m(2, 136, d)
155
# define BOOST_PP_REPEAT_1_138(m, d) BOOST_PP_REPEAT_1_137(m, d) m(2, 137, d)
156
# define BOOST_PP_REPEAT_1_139(m, d) BOOST_PP_REPEAT_1_138(m, d) m(2, 138, d)
157
# define BOOST_PP_REPEAT_1_140(m, d) BOOST_PP_REPEAT_1_139(m, d) m(2, 139, d)
158
# define BOOST_PP_REPEAT_1_141(m, d) BOOST_PP_REPEAT_1_140(m, d) m(2, 140, d)
159
# define BOOST_PP_REPEAT_1_142(m, d) BOOST_PP_REPEAT_1_141(m, d) m(2, 141, d)
160
# define BOOST_PP_REPEAT_1_143(m, d) BOOST_PP_REPEAT_1_142(m, d) m(2, 142, d)
161
# define BOOST_PP_REPEAT_1_144(m, d) BOOST_PP_REPEAT_1_143(m, d) m(2, 143, d)
162
# define BOOST_PP_REPEAT_1_145(m, d) BOOST_PP_REPEAT_1_144(m, d) m(2, 144, d)
163
# define BOOST_PP_REPEAT_1_146(m, d) BOOST_PP_REPEAT_1_145(m, d) m(2, 145, d)
164
# define BOOST_PP_REPEAT_1_147(m, d) BOOST_PP_REPEAT_1_146(m, d) m(2, 146, d)
165
# define BOOST_PP_REPEAT_1_148(m, d) BOOST_PP_REPEAT_1_147(m, d) m(2, 147, d)
166
# define BOOST_PP_REPEAT_1_149(m, d) BOOST_PP_REPEAT_1_148(m, d) m(2, 148, d)
167
# define BOOST_PP_REPEAT_1_150(m, d) BOOST_PP_REPEAT_1_149(m, d) m(2, 149, d)
168
# define BOOST_PP_REPEAT_1_151(m, d) BOOST_PP_REPEAT_1_150(m, d) m(2, 150, d)
169
# define BOOST_PP_REPEAT_1_152(m, d) BOOST_PP_REPEAT_1_151(m, d) m(2, 151, d)
170
# define BOOST_PP_REPEAT_1_153(m, d) BOOST_PP_REPEAT_1_152(m, d) m(2, 152, d)
171
# define BOOST_PP_REPEAT_1_154(m, d) BOOST_PP_REPEAT_1_153(m, d) m(2, 153, d)
172
# define BOOST_PP_REPEAT_1_155(m, d) BOOST_PP_REPEAT_1_154(m, d) m(2, 154, d)
173
# define BOOST_PP_REPEAT_1_156(m, d) BOOST_PP_REPEAT_1_155(m, d) m(2, 155, d)
174
# define BOOST_PP_REPEAT_1_157(m, d) BOOST_PP_REPEAT_1_156(m, d) m(2, 156, d)
175
# define BOOST_PP_REPEAT_1_158(m, d) BOOST_PP_REPEAT_1_157(m, d) m(2, 157, d)
176
# define BOOST_PP_REPEAT_1_159(m, d) BOOST_PP_REPEAT_1_158(m, d) m(2, 158, d)
177
# define BOOST_PP_REPEAT_1_160(m, d) BOOST_PP_REPEAT_1_159(m, d) m(2, 159, d)
178
# define BOOST_PP_REPEAT_1_161(m, d) BOOST_PP_REPEAT_1_160(m, d) m(2, 160, d)
179
# define BOOST_PP_REPEAT_1_162(m, d) BOOST_PP_REPEAT_1_161(m, d) m(2, 161, d)
180
# define BOOST_PP_REPEAT_1_163(m, d) BOOST_PP_REPEAT_1_162(m, d) m(2, 162, d)
181
# define BOOST_PP_REPEAT_1_164(m, d) BOOST_PP_REPEAT_1_163(m, d) m(2, 163, d)
182
# define BOOST_PP_REPEAT_1_165(m, d) BOOST_PP_REPEAT_1_164(m, d) m(2, 164, d)
183
# define BOOST_PP_REPEAT_1_166(m, d) BOOST_PP_REPEAT_1_165(m, d) m(2, 165, d)
184
# define BOOST_PP_REPEAT_1_167(m, d) BOOST_PP_REPEAT_1_166(m, d) m(2, 166, d)
185
# define BOOST_PP_REPEAT_1_168(m, d) BOOST_PP_REPEAT_1_167(m, d) m(2, 167, d)
186
# define BOOST_PP_REPEAT_1_169(m, d) BOOST_PP_REPEAT_1_168(m, d) m(2, 168, d)
187
# define BOOST_PP_REPEAT_1_170(m, d) BOOST_PP_REPEAT_1_169(m, d) m(2, 169, d)
188
# define BOOST_PP_REPEAT_1_171(m, d) BOOST_PP_REPEAT_1_170(m, d) m(2, 170, d)
189
# define BOOST_PP_REPEAT_1_172(m, d) BOOST_PP_REPEAT_1_171(m, d) m(2, 171, d)
190
# define BOOST_PP_REPEAT_1_173(m, d) BOOST_PP_REPEAT_1_172(m, d) m(2, 172, d)
191
# define BOOST_PP_REPEAT_1_174(m, d) BOOST_PP_REPEAT_1_173(m, d) m(2, 173, d)
192
# define BOOST_PP_REPEAT_1_175(m, d) BOOST_PP_REPEAT_1_174(m, d) m(2, 174, d)
193
# define BOOST_PP_REPEAT_1_176(m, d) BOOST_PP_REPEAT_1_175(m, d) m(2, 175, d)
194
# define BOOST_PP_REPEAT_1_177(m, d) BOOST_PP_REPEAT_1_176(m, d) m(2, 176, d)
195
# define BOOST_PP_REPEAT_1_178(m, d) BOOST_PP_REPEAT_1_177(m, d) m(2, 177, d)
196
# define BOOST_PP_REPEAT_1_179(m, d) BOOST_PP_REPEAT_1_178(m, d) m(2, 178, d)
197
# define BOOST_PP_REPEAT_1_180(m, d) BOOST_PP_REPEAT_1_179(m, d) m(2, 179, d)
198
# define BOOST_PP_REPEAT_1_181(m, d) BOOST_PP_REPEAT_1_180(m, d) m(2, 180, d)
199
# define BOOST_PP_REPEAT_1_182(m, d) BOOST_PP_REPEAT_1_181(m, d) m(2, 181, d)
200
# define BOOST_PP_REPEAT_1_183(m, d) BOOST_PP_REPEAT_1_182(m, d) m(2, 182, d)
201
# define BOOST_PP_REPEAT_1_184(m, d) BOOST_PP_REPEAT_1_183(m, d) m(2, 183, d)
202
# define BOOST_PP_REPEAT_1_185(m, d) BOOST_PP_REPEAT_1_184(m, d) m(2, 184, d)
203
# define BOOST_PP_REPEAT_1_186(m, d) BOOST_PP_REPEAT_1_185(m, d) m(2, 185, d)
204
# define BOOST_PP_REPEAT_1_187(m, d) BOOST_PP_REPEAT_1_186(m, d) m(2, 186, d)
205
# define BOOST_PP_REPEAT_1_188(m, d) BOOST_PP_REPEAT_1_187(m, d) m(2, 187, d)
206
# define BOOST_PP_REPEAT_1_189(m, d) BOOST_PP_REPEAT_1_188(m, d) m(2, 188, d)
207
# define BOOST_PP_REPEAT_1_190(m, d) BOOST_PP_REPEAT_1_189(m, d) m(2, 189, d)
208
# define BOOST_PP_REPEAT_1_191(m, d) BOOST_PP_REPEAT_1_190(m, d) m(2, 190, d)
209
# define BOOST_PP_REPEAT_1_192(m, d) BOOST_PP_REPEAT_1_191(m, d) m(2, 191, d)
210
# define BOOST_PP_REPEAT_1_193(m, d) BOOST_PP_REPEAT_1_192(m, d) m(2, 192, d)
211
# define BOOST_PP_REPEAT_1_194(m, d) BOOST_PP_REPEAT_1_193(m, d) m(2, 193, d)
212
# define BOOST_PP_REPEAT_1_195(m, d) BOOST_PP_REPEAT_1_194(m, d) m(2, 194, d)
213
# define BOOST_PP_REPEAT_1_196(m, d) BOOST_PP_REPEAT_1_195(m, d) m(2, 195, d)
214
# define BOOST_PP_REPEAT_1_197(m, d) BOOST_PP_REPEAT_1_196(m, d) m(2, 196, d)
215
# define BOOST_PP_REPEAT_1_198(m, d) BOOST_PP_REPEAT_1_197(m, d) m(2, 197, d)
216
# define BOOST_PP_REPEAT_1_199(m, d) BOOST_PP_REPEAT_1_198(m, d) m(2, 198, d)
217
# define BOOST_PP_REPEAT_1_200(m, d) BOOST_PP_REPEAT_1_199(m, d) m(2, 199, d)
218
# define BOOST_PP_REPEAT_1_201(m, d) BOOST_PP_REPEAT_1_200(m, d) m(2, 200, d)
219
# define BOOST_PP_REPEAT_1_202(m, d) BOOST_PP_REPEAT_1_201(m, d) m(2, 201, d)
220
# define BOOST_PP_REPEAT_1_203(m, d) BOOST_PP_REPEAT_1_202(m, d) m(2, 202, d)
221
# define BOOST_PP_REPEAT_1_204(m, d) BOOST_PP_REPEAT_1_203(m, d) m(2, 203, d)
222
# define BOOST_PP_REPEAT_1_205(m, d) BOOST_PP_REPEAT_1_204(m, d) m(2, 204, d)
223
# define BOOST_PP_REPEAT_1_206(m, d) BOOST_PP_REPEAT_1_205(m, d) m(2, 205, d)
224
# define BOOST_PP_REPEAT_1_207(m, d) BOOST_PP_REPEAT_1_206(m, d) m(2, 206, d)
225
# define BOOST_PP_REPEAT_1_208(m, d) BOOST_PP_REPEAT_1_207(m, d) m(2, 207, d)
226
# define BOOST_PP_REPEAT_1_209(m, d) BOOST_PP_REPEAT_1_208(m, d) m(2, 208, d)
227
# define BOOST_PP_REPEAT_1_210(m, d) BOOST_PP_REPEAT_1_209(m, d) m(2, 209, d)
228
# define BOOST_PP_REPEAT_1_211(m, d) BOOST_PP_REPEAT_1_210(m, d) m(2, 210, d)
229
# define BOOST_PP_REPEAT_1_212(m, d) BOOST_PP_REPEAT_1_211(m, d) m(2, 211, d)
230
# define BOOST_PP_REPEAT_1_213(m, d) BOOST_PP_REPEAT_1_212(m, d) m(2, 212, d)
231
# define BOOST_PP_REPEAT_1_214(m, d) BOOST_PP_REPEAT_1_213(m, d) m(2, 213, d)
232
# define BOOST_PP_REPEAT_1_215(m, d) BOOST_PP_REPEAT_1_214(m, d) m(2, 214, d)
233
# define BOOST_PP_REPEAT_1_216(m, d) BOOST_PP_REPEAT_1_215(m, d) m(2, 215, d)
234
# define BOOST_PP_REPEAT_1_217(m, d) BOOST_PP_REPEAT_1_216(m, d) m(2, 216, d)
235
# define BOOST_PP_REPEAT_1_218(m, d) BOOST_PP_REPEAT_1_217(m, d) m(2, 217, d)
236
# define BOOST_PP_REPEAT_1_219(m, d) BOOST_PP_REPEAT_1_218(m, d) m(2, 218, d)
237
# define BOOST_PP_REPEAT_1_220(m, d) BOOST_PP_REPEAT_1_219(m, d) m(2, 219, d)
238
# define BOOST_PP_REPEAT_1_221(m, d) BOOST_PP_REPEAT_1_220(m, d) m(2, 220, d)
239
# define BOOST_PP_REPEAT_1_222(m, d) BOOST_PP_REPEAT_1_221(m, d) m(2, 221, d)
240
# define BOOST_PP_REPEAT_1_223(m, d) BOOST_PP_REPEAT_1_222(m, d) m(2, 222, d)
241
# define BOOST_PP_REPEAT_1_224(m, d) BOOST_PP_REPEAT_1_223(m, d) m(2, 223, d)
242
# define BOOST_PP_REPEAT_1_225(m, d) BOOST_PP_REPEAT_1_224(m, d) m(2, 224, d)
243
# define BOOST_PP_REPEAT_1_226(m, d) BOOST_PP_REPEAT_1_225(m, d) m(2, 225, d)
244
# define BOOST_PP_REPEAT_1_227(m, d) BOOST_PP_REPEAT_1_226(m, d) m(2, 226, d)
245
# define BOOST_PP_REPEAT_1_228(m, d) BOOST_PP_REPEAT_1_227(m, d) m(2, 227, d)
246
# define BOOST_PP_REPEAT_1_229(m, d) BOOST_PP_REPEAT_1_228(m, d) m(2, 228, d)
247
# define BOOST_PP_REPEAT_1_230(m, d) BOOST_PP_REPEAT_1_229(m, d) m(2, 229, d)
248
# define BOOST_PP_REPEAT_1_231(m, d) BOOST_PP_REPEAT_1_230(m, d) m(2, 230, d)
249
# define BOOST_PP_REPEAT_1_232(m, d) BOOST_PP_REPEAT_1_231(m, d) m(2, 231, d)
250
# define BOOST_PP_REPEAT_1_233(m, d) BOOST_PP_REPEAT_1_232(m, d) m(2, 232, d)
251
# define BOOST_PP_REPEAT_1_234(m, d) BOOST_PP_REPEAT_1_233(m, d) m(2, 233, d)
252
# define BOOST_PP_REPEAT_1_235(m, d) BOOST_PP_REPEAT_1_234(m, d) m(2, 234, d)
253
# define BOOST_PP_REPEAT_1_236(m, d) BOOST_PP_REPEAT_1_235(m, d) m(2, 235, d)
254
# define BOOST_PP_REPEAT_1_237(m, d) BOOST_PP_REPEAT_1_236(m, d) m(2, 236, d)
255
# define BOOST_PP_REPEAT_1_238(m, d) BOOST_PP_REPEAT_1_237(m, d) m(2, 237, d)
256
# define BOOST_PP_REPEAT_1_239(m, d) BOOST_PP_REPEAT_1_238(m, d) m(2, 238, d)
257
# define BOOST_PP_REPEAT_1_240(m, d) BOOST_PP_REPEAT_1_239(m, d) m(2, 239, d)
258
# define BOOST_PP_REPEAT_1_241(m, d) BOOST_PP_REPEAT_1_240(m, d) m(2, 240, d)
259
# define BOOST_PP_REPEAT_1_242(m, d) BOOST_PP_REPEAT_1_241(m, d) m(2, 241, d)
260
# define BOOST_PP_REPEAT_1_243(m, d) BOOST_PP_REPEAT_1_242(m, d) m(2, 242, d)
261
# define BOOST_PP_REPEAT_1_244(m, d) BOOST_PP_REPEAT_1_243(m, d) m(2, 243, d)
262
# define BOOST_PP_REPEAT_1_245(m, d) BOOST_PP_REPEAT_1_244(m, d) m(2, 244, d)
263
# define BOOST_PP_REPEAT_1_246(m, d) BOOST_PP_REPEAT_1_245(m, d) m(2, 245, d)
264
# define BOOST_PP_REPEAT_1_247(m, d) BOOST_PP_REPEAT_1_246(m, d) m(2, 246, d)
265
# define BOOST_PP_REPEAT_1_248(m, d) BOOST_PP_REPEAT_1_247(m, d) m(2, 247, d)
266
# define BOOST_PP_REPEAT_1_249(m, d) BOOST_PP_REPEAT_1_248(m, d) m(2, 248, d)
267
# define BOOST_PP_REPEAT_1_250(m, d) BOOST_PP_REPEAT_1_249(m, d) m(2, 249, d)
268
# define BOOST_PP_REPEAT_1_251(m, d) BOOST_PP_REPEAT_1_250(m, d) m(2, 250, d)
269
# define BOOST_PP_REPEAT_1_252(m, d) BOOST_PP_REPEAT_1_251(m, d) m(2, 251, d)
270
# define BOOST_PP_REPEAT_1_253(m, d) BOOST_PP_REPEAT_1_252(m, d) m(2, 252, d)
271
# define BOOST_PP_REPEAT_1_254(m, d) BOOST_PP_REPEAT_1_253(m, d) m(2, 253, d)
272
# define BOOST_PP_REPEAT_1_255(m, d) BOOST_PP_REPEAT_1_254(m, d) m(2, 254, d)
273
# define BOOST_PP_REPEAT_1_256(m, d) BOOST_PP_REPEAT_1_255(m, d) m(2, 255, d)
274
#
275
# define BOOST_PP_REPEAT_2_0(m, d)
276
# define BOOST_PP_REPEAT_2_1(m, d) m(3, 0, d)
277
# define BOOST_PP_REPEAT_2_2(m, d) BOOST_PP_REPEAT_2_1(m, d) m(3, 1, d)
278
# define BOOST_PP_REPEAT_2_3(m, d) BOOST_PP_REPEAT_2_2(m, d) m(3, 2, d)
279
# define BOOST_PP_REPEAT_2_4(m, d) BOOST_PP_REPEAT_2_3(m, d) m(3, 3, d)
280
# define BOOST_PP_REPEAT_2_5(m, d) BOOST_PP_REPEAT_2_4(m, d) m(3, 4, d)
281
# define BOOST_PP_REPEAT_2_6(m, d) BOOST_PP_REPEAT_2_5(m, d) m(3, 5, d)
282
# define BOOST_PP_REPEAT_2_7(m, d) BOOST_PP_REPEAT_2_6(m, d) m(3, 6, d)
283
# define BOOST_PP_REPEAT_2_8(m, d) BOOST_PP_REPEAT_2_7(m, d) m(3, 7, d)
284
# define BOOST_PP_REPEAT_2_9(m, d) BOOST_PP_REPEAT_2_8(m, d) m(3, 8, d)
285
# define BOOST_PP_REPEAT_2_10(m, d) BOOST_PP_REPEAT_2_9(m, d) m(3, 9, d)
286
# define BOOST_PP_REPEAT_2_11(m, d) BOOST_PP_REPEAT_2_10(m, d) m(3, 10, d)
287
# define BOOST_PP_REPEAT_2_12(m, d) BOOST_PP_REPEAT_2_11(m, d) m(3, 11, d)
288
# define BOOST_PP_REPEAT_2_13(m, d) BOOST_PP_REPEAT_2_12(m, d) m(3, 12, d)
289
# define BOOST_PP_REPEAT_2_14(m, d) BOOST_PP_REPEAT_2_13(m, d) m(3, 13, d)
290
# define BOOST_PP_REPEAT_2_15(m, d) BOOST_PP_REPEAT_2_14(m, d) m(3, 14, d)
291
# define BOOST_PP_REPEAT_2_16(m, d) BOOST_PP_REPEAT_2_15(m, d) m(3, 15, d)
292
# define BOOST_PP_REPEAT_2_17(m, d) BOOST_PP_REPEAT_2_16(m, d) m(3, 16, d)
293
# define BOOST_PP_REPEAT_2_18(m, d) BOOST_PP_REPEAT_2_17(m, d) m(3, 17, d)
294
# define BOOST_PP_REPEAT_2_19(m, d) BOOST_PP_REPEAT_2_18(m, d) m(3, 18, d)
295
# define BOOST_PP_REPEAT_2_20(m, d) BOOST_PP_REPEAT_2_19(m, d) m(3, 19, d)
296
# define BOOST_PP_REPEAT_2_21(m, d) BOOST_PP_REPEAT_2_20(m, d) m(3, 20, d)
297
# define BOOST_PP_REPEAT_2_22(m, d) BOOST_PP_REPEAT_2_21(m, d) m(3, 21, d)
298
# define BOOST_PP_REPEAT_2_23(m, d) BOOST_PP_REPEAT_2_22(m, d) m(3, 22, d)
299
# define BOOST_PP_REPEAT_2_24(m, d) BOOST_PP_REPEAT_2_23(m, d) m(3, 23, d)
300
# define BOOST_PP_REPEAT_2_25(m, d) BOOST_PP_REPEAT_2_24(m, d) m(3, 24, d)
301
# define BOOST_PP_REPEAT_2_26(m, d) BOOST_PP_REPEAT_2_25(m, d) m(3, 25, d)
302
# define BOOST_PP_REPEAT_2_27(m, d) BOOST_PP_REPEAT_2_26(m, d) m(3, 26, d)
303
# define BOOST_PP_REPEAT_2_28(m, d) BOOST_PP_REPEAT_2_27(m, d) m(3, 27, d)
304
# define BOOST_PP_REPEAT_2_29(m, d) BOOST_PP_REPEAT_2_28(m, d) m(3, 28, d)
305
# define BOOST_PP_REPEAT_2_30(m, d) BOOST_PP_REPEAT_2_29(m, d) m(3, 29, d)
306
# define BOOST_PP_REPEAT_2_31(m, d) BOOST_PP_REPEAT_2_30(m, d) m(3, 30, d)
307
# define BOOST_PP_REPEAT_2_32(m, d) BOOST_PP_REPEAT_2_31(m, d) m(3, 31, d)
308
# define BOOST_PP_REPEAT_2_33(m, d) BOOST_PP_REPEAT_2_32(m, d) m(3, 32, d)
309
# define BOOST_PP_REPEAT_2_34(m, d) BOOST_PP_REPEAT_2_33(m, d) m(3, 33, d)
310
# define BOOST_PP_REPEAT_2_35(m, d) BOOST_PP_REPEAT_2_34(m, d) m(3, 34, d)
311
# define BOOST_PP_REPEAT_2_36(m, d) BOOST_PP_REPEAT_2_35(m, d) m(3, 35, d)
312
# define BOOST_PP_REPEAT_2_37(m, d) BOOST_PP_REPEAT_2_36(m, d) m(3, 36, d)
313
# define BOOST_PP_REPEAT_2_38(m, d) BOOST_PP_REPEAT_2_37(m, d) m(3, 37, d)
314
# define BOOST_PP_REPEAT_2_39(m, d) BOOST_PP_REPEAT_2_38(m, d) m(3, 38, d)
315
# define BOOST_PP_REPEAT_2_40(m, d) BOOST_PP_REPEAT_2_39(m, d) m(3, 39, d)
316
# define BOOST_PP_REPEAT_2_41(m, d) BOOST_PP_REPEAT_2_40(m, d) m(3, 40, d)
317
# define BOOST_PP_REPEAT_2_42(m, d) BOOST_PP_REPEAT_2_41(m, d) m(3, 41, d)
318
# define BOOST_PP_REPEAT_2_43(m, d) BOOST_PP_REPEAT_2_42(m, d) m(3, 42, d)
319
# define BOOST_PP_REPEAT_2_44(m, d) BOOST_PP_REPEAT_2_43(m, d) m(3, 43, d)
320
# define BOOST_PP_REPEAT_2_45(m, d) BOOST_PP_REPEAT_2_44(m, d) m(3, 44, d)
321
# define BOOST_PP_REPEAT_2_46(m, d) BOOST_PP_REPEAT_2_45(m, d) m(3, 45, d)
322
# define BOOST_PP_REPEAT_2_47(m, d) BOOST_PP_REPEAT_2_46(m, d) m(3, 46, d)
323
# define BOOST_PP_REPEAT_2_48(m, d) BOOST_PP_REPEAT_2_47(m, d) m(3, 47, d)
324
# define BOOST_PP_REPEAT_2_49(m, d) BOOST_PP_REPEAT_2_48(m, d) m(3, 48, d)
325
# define BOOST_PP_REPEAT_2_50(m, d) BOOST_PP_REPEAT_2_49(m, d) m(3, 49, d)
326
# define BOOST_PP_REPEAT_2_51(m, d) BOOST_PP_REPEAT_2_50(m, d) m(3, 50, d)
327
# define BOOST_PP_REPEAT_2_52(m, d) BOOST_PP_REPEAT_2_51(m, d) m(3, 51, d)
328
# define BOOST_PP_REPEAT_2_53(m, d) BOOST_PP_REPEAT_2_52(m, d) m(3, 52, d)
329
# define BOOST_PP_REPEAT_2_54(m, d) BOOST_PP_REPEAT_2_53(m, d) m(3, 53, d)
330
# define BOOST_PP_REPEAT_2_55(m, d) BOOST_PP_REPEAT_2_54(m, d) m(3, 54, d)
331
# define BOOST_PP_REPEAT_2_56(m, d) BOOST_PP_REPEAT_2_55(m, d) m(3, 55, d)
332
# define BOOST_PP_REPEAT_2_57(m, d) BOOST_PP_REPEAT_2_56(m, d) m(3, 56, d)
333
# define BOOST_PP_REPEAT_2_58(m, d) BOOST_PP_REPEAT_2_57(m, d) m(3, 57, d)
334
# define BOOST_PP_REPEAT_2_59(m, d) BOOST_PP_REPEAT_2_58(m, d) m(3, 58, d)
335
# define BOOST_PP_REPEAT_2_60(m, d) BOOST_PP_REPEAT_2_59(m, d) m(3, 59, d)
336
# define BOOST_PP_REPEAT_2_61(m, d) BOOST_PP_REPEAT_2_60(m, d) m(3, 60, d)
337
# define BOOST_PP_REPEAT_2_62(m, d) BOOST_PP_REPEAT_2_61(m, d) m(3, 61, d)
338
# define BOOST_PP_REPEAT_2_63(m, d) BOOST_PP_REPEAT_2_62(m, d) m(3, 62, d)
339
# define BOOST_PP_REPEAT_2_64(m, d) BOOST_PP_REPEAT_2_63(m, d) m(3, 63, d)
340
# define BOOST_PP_REPEAT_2_65(m, d) BOOST_PP_REPEAT_2_64(m, d) m(3, 64, d)
341
# define BOOST_PP_REPEAT_2_66(m, d) BOOST_PP_REPEAT_2_65(m, d) m(3, 65, d)
342
# define BOOST_PP_REPEAT_2_67(m, d) BOOST_PP_REPEAT_2_66(m, d) m(3, 66, d)
343
# define BOOST_PP_REPEAT_2_68(m, d) BOOST_PP_REPEAT_2_67(m, d) m(3, 67, d)
344
# define BOOST_PP_REPEAT_2_69(m, d) BOOST_PP_REPEAT_2_68(m, d) m(3, 68, d)
345
# define BOOST_PP_REPEAT_2_70(m, d) BOOST_PP_REPEAT_2_69(m, d) m(3, 69, d)
346
# define BOOST_PP_REPEAT_2_71(m, d) BOOST_PP_REPEAT_2_70(m, d) m(3, 70, d)
347
# define BOOST_PP_REPEAT_2_72(m, d) BOOST_PP_REPEAT_2_71(m, d) m(3, 71, d)
348
# define BOOST_PP_REPEAT_2_73(m, d) BOOST_PP_REPEAT_2_72(m, d) m(3, 72, d)
349
# define BOOST_PP_REPEAT_2_74(m, d) BOOST_PP_REPEAT_2_73(m, d) m(3, 73, d)
350
# define BOOST_PP_REPEAT_2_75(m, d) BOOST_PP_REPEAT_2_74(m, d) m(3, 74, d)
351
# define BOOST_PP_REPEAT_2_76(m, d) BOOST_PP_REPEAT_2_75(m, d) m(3, 75, d)
352
# define BOOST_PP_REPEAT_2_77(m, d) BOOST_PP_REPEAT_2_76(m, d) m(3, 76, d)
353
# define BOOST_PP_REPEAT_2_78(m, d) BOOST_PP_REPEAT_2_77(m, d) m(3, 77, d)
354
# define BOOST_PP_REPEAT_2_79(m, d) BOOST_PP_REPEAT_2_78(m, d) m(3, 78, d)
355
# define BOOST_PP_REPEAT_2_80(m, d) BOOST_PP_REPEAT_2_79(m, d) m(3, 79, d)
356
# define BOOST_PP_REPEAT_2_81(m, d) BOOST_PP_REPEAT_2_80(m, d) m(3, 80, d)
357
# define BOOST_PP_REPEAT_2_82(m, d) BOOST_PP_REPEAT_2_81(m, d) m(3, 81, d)
358
# define BOOST_PP_REPEAT_2_83(m, d) BOOST_PP_REPEAT_2_82(m, d) m(3, 82, d)
359
# define BOOST_PP_REPEAT_2_84(m, d) BOOST_PP_REPEAT_2_83(m, d) m(3, 83, d)
360
# define BOOST_PP_REPEAT_2_85(m, d) BOOST_PP_REPEAT_2_84(m, d) m(3, 84, d)
361
# define BOOST_PP_REPEAT_2_86(m, d) BOOST_PP_REPEAT_2_85(m, d) m(3, 85, d)
362
# define BOOST_PP_REPEAT_2_87(m, d) BOOST_PP_REPEAT_2_86(m, d) m(3, 86, d)
363
# define BOOST_PP_REPEAT_2_88(m, d) BOOST_PP_REPEAT_2_87(m, d) m(3, 87, d)
364
# define BOOST_PP_REPEAT_2_89(m, d) BOOST_PP_REPEAT_2_88(m, d) m(3, 88, d)
365
# define BOOST_PP_REPEAT_2_90(m, d) BOOST_PP_REPEAT_2_89(m, d) m(3, 89, d)
366
# define BOOST_PP_REPEAT_2_91(m, d) BOOST_PP_REPEAT_2_90(m, d) m(3, 90, d)
367
# define BOOST_PP_REPEAT_2_92(m, d) BOOST_PP_REPEAT_2_91(m, d) m(3, 91, d)
368
# define BOOST_PP_REPEAT_2_93(m, d) BOOST_PP_REPEAT_2_92(m, d) m(3, 92, d)
369
# define BOOST_PP_REPEAT_2_94(m, d) BOOST_PP_REPEAT_2_93(m, d) m(3, 93, d)
370
# define BOOST_PP_REPEAT_2_95(m, d) BOOST_PP_REPEAT_2_94(m, d) m(3, 94, d)
371
# define BOOST_PP_REPEAT_2_96(m, d) BOOST_PP_REPEAT_2_95(m, d) m(3, 95, d)
372
# define BOOST_PP_REPEAT_2_97(m, d) BOOST_PP_REPEAT_2_96(m, d) m(3, 96, d)
373
# define BOOST_PP_REPEAT_2_98(m, d) BOOST_PP_REPEAT_2_97(m, d) m(3, 97, d)
374
# define BOOST_PP_REPEAT_2_99(m, d) BOOST_PP_REPEAT_2_98(m, d) m(3, 98, d)
375
# define BOOST_PP_REPEAT_2_100(m, d) BOOST_PP_REPEAT_2_99(m, d) m(3, 99, d)
376
# define BOOST_PP_REPEAT_2_101(m, d) BOOST_PP_REPEAT_2_100(m, d) m(3, 100, d)
377
# define BOOST_PP_REPEAT_2_102(m, d) BOOST_PP_REPEAT_2_101(m, d) m(3, 101, d)
378
# define BOOST_PP_REPEAT_2_103(m, d) BOOST_PP_REPEAT_2_102(m, d) m(3, 102, d)
379
# define BOOST_PP_REPEAT_2_104(m, d) BOOST_PP_REPEAT_2_103(m, d) m(3, 103, d)
380
# define BOOST_PP_REPEAT_2_105(m, d) BOOST_PP_REPEAT_2_104(m, d) m(3, 104, d)
381
# define BOOST_PP_REPEAT_2_106(m, d) BOOST_PP_REPEAT_2_105(m, d) m(3, 105, d)
382
# define BOOST_PP_REPEAT_2_107(m, d) BOOST_PP_REPEAT_2_106(m, d) m(3, 106, d)
383
# define BOOST_PP_REPEAT_2_108(m, d) BOOST_PP_REPEAT_2_107(m, d) m(3, 107, d)
384
# define BOOST_PP_REPEAT_2_109(m, d) BOOST_PP_REPEAT_2_108(m, d) m(3, 108, d)
385
# define BOOST_PP_REPEAT_2_110(m, d) BOOST_PP_REPEAT_2_109(m, d) m(3, 109, d)
386
# define BOOST_PP_REPEAT_2_111(m, d) BOOST_PP_REPEAT_2_110(m, d) m(3, 110, d)
387
# define BOOST_PP_REPEAT_2_112(m, d) BOOST_PP_REPEAT_2_111(m, d) m(3, 111, d)
388
# define BOOST_PP_REPEAT_2_113(m, d) BOOST_PP_REPEAT_2_112(m, d) m(3, 112, d)
389
# define BOOST_PP_REPEAT_2_114(m, d) BOOST_PP_REPEAT_2_113(m, d) m(3, 113, d)
390
# define BOOST_PP_REPEAT_2_115(m, d) BOOST_PP_REPEAT_2_114(m, d) m(3, 114, d)
391
# define BOOST_PP_REPEAT_2_116(m, d) BOOST_PP_REPEAT_2_115(m, d) m(3, 115, d)
392
# define BOOST_PP_REPEAT_2_117(m, d) BOOST_PP_REPEAT_2_116(m, d) m(3, 116, d)
393
# define BOOST_PP_REPEAT_2_118(m, d) BOOST_PP_REPEAT_2_117(m, d) m(3, 117, d)
394
# define BOOST_PP_REPEAT_2_119(m, d) BOOST_PP_REPEAT_2_118(m, d) m(3, 118, d)
395
# define BOOST_PP_REPEAT_2_120(m, d) BOOST_PP_REPEAT_2_119(m, d) m(3, 119, d)
396
# define BOOST_PP_REPEAT_2_121(m, d) BOOST_PP_REPEAT_2_120(m, d) m(3, 120, d)
397
# define BOOST_PP_REPEAT_2_122(m, d) BOOST_PP_REPEAT_2_121(m, d) m(3, 121, d)
398
# define BOOST_PP_REPEAT_2_123(m, d) BOOST_PP_REPEAT_2_122(m, d) m(3, 122, d)
399
# define BOOST_PP_REPEAT_2_124(m, d) BOOST_PP_REPEAT_2_123(m, d) m(3, 123, d)
400
# define BOOST_PP_REPEAT_2_125(m, d) BOOST_PP_REPEAT_2_124(m, d) m(3, 124, d)
401
# define BOOST_PP_REPEAT_2_126(m, d) BOOST_PP_REPEAT_2_125(m, d) m(3, 125, d)
402
# define BOOST_PP_REPEAT_2_127(m, d) BOOST_PP_REPEAT_2_126(m, d) m(3, 126, d)
403
# define BOOST_PP_REPEAT_2_128(m, d) BOOST_PP_REPEAT_2_127(m, d) m(3, 127, d)
404
# define BOOST_PP_REPEAT_2_129(m, d) BOOST_PP_REPEAT_2_128(m, d) m(3, 128, d)
405
# define BOOST_PP_REPEAT_2_130(m, d) BOOST_PP_REPEAT_2_129(m, d) m(3, 129, d)
406
# define BOOST_PP_REPEAT_2_131(m, d) BOOST_PP_REPEAT_2_130(m, d) m(3, 130, d)
407
# define BOOST_PP_REPEAT_2_132(m, d) BOOST_PP_REPEAT_2_131(m, d) m(3, 131, d)
408
# define BOOST_PP_REPEAT_2_133(m, d) BOOST_PP_REPEAT_2_132(m, d) m(3, 132, d)
409
# define BOOST_PP_REPEAT_2_134(m, d) BOOST_PP_REPEAT_2_133(m, d) m(3, 133, d)
410
# define BOOST_PP_REPEAT_2_135(m, d) BOOST_PP_REPEAT_2_134(m, d) m(3, 134, d)
411
# define BOOST_PP_REPEAT_2_136(m, d) BOOST_PP_REPEAT_2_135(m, d) m(3, 135, d)
412
# define BOOST_PP_REPEAT_2_137(m, d) BOOST_PP_REPEAT_2_136(m, d) m(3, 136, d)
413
# define BOOST_PP_REPEAT_2_138(m, d) BOOST_PP_REPEAT_2_137(m, d) m(3, 137, d)
414
# define BOOST_PP_REPEAT_2_139(m, d) BOOST_PP_REPEAT_2_138(m, d) m(3, 138, d)
415
# define BOOST_PP_REPEAT_2_140(m, d) BOOST_PP_REPEAT_2_139(m, d) m(3, 139, d)
416
# define BOOST_PP_REPEAT_2_141(m, d) BOOST_PP_REPEAT_2_140(m, d) m(3, 140, d)
417
# define BOOST_PP_REPEAT_2_142(m, d) BOOST_PP_REPEAT_2_141(m, d) m(3, 141, d)
418
# define BOOST_PP_REPEAT_2_143(m, d) BOOST_PP_REPEAT_2_142(m, d) m(3, 142, d)
419
# define BOOST_PP_REPEAT_2_144(m, d) BOOST_PP_REPEAT_2_143(m, d) m(3, 143, d)
420
# define BOOST_PP_REPEAT_2_145(m, d) BOOST_PP_REPEAT_2_144(m, d) m(3, 144, d)
421
# define BOOST_PP_REPEAT_2_146(m, d) BOOST_PP_REPEAT_2_145(m, d) m(3, 145, d)
422
# define BOOST_PP_REPEAT_2_147(m, d) BOOST_PP_REPEAT_2_146(m, d) m(3, 146, d)
423
# define BOOST_PP_REPEAT_2_148(m, d) BOOST_PP_REPEAT_2_147(m, d) m(3, 147, d)
424
# define BOOST_PP_REPEAT_2_149(m, d) BOOST_PP_REPEAT_2_148(m, d) m(3, 148, d)
425
# define BOOST_PP_REPEAT_2_150(m, d) BOOST_PP_REPEAT_2_149(m, d) m(3, 149, d)
426
# define BOOST_PP_REPEAT_2_151(m, d) BOOST_PP_REPEAT_2_150(m, d) m(3, 150, d)
427
# define BOOST_PP_REPEAT_2_152(m, d) BOOST_PP_REPEAT_2_151(m, d) m(3, 151, d)
428
# define BOOST_PP_REPEAT_2_153(m, d) BOOST_PP_REPEAT_2_152(m, d) m(3, 152, d)
429
# define BOOST_PP_REPEAT_2_154(m, d) BOOST_PP_REPEAT_2_153(m, d) m(3, 153, d)
430
# define BOOST_PP_REPEAT_2_155(m, d) BOOST_PP_REPEAT_2_154(m, d) m(3, 154, d)
431
# define BOOST_PP_REPEAT_2_156(m, d) BOOST_PP_REPEAT_2_155(m, d) m(3, 155, d)
432
# define BOOST_PP_REPEAT_2_157(m, d) BOOST_PP_REPEAT_2_156(m, d) m(3, 156, d)
433
# define BOOST_PP_REPEAT_2_158(m, d) BOOST_PP_REPEAT_2_157(m, d) m(3, 157, d)
434
# define BOOST_PP_REPEAT_2_159(m, d) BOOST_PP_REPEAT_2_158(m, d) m(3, 158, d)
435
# define BOOST_PP_REPEAT_2_160(m, d) BOOST_PP_REPEAT_2_159(m, d) m(3, 159, d)
436
# define BOOST_PP_REPEAT_2_161(m, d) BOOST_PP_REPEAT_2_160(m, d) m(3, 160, d)
437
# define BOOST_PP_REPEAT_2_162(m, d) BOOST_PP_REPEAT_2_161(m, d) m(3, 161, d)
438
# define BOOST_PP_REPEAT_2_163(m, d) BOOST_PP_REPEAT_2_162(m, d) m(3, 162, d)
439
# define BOOST_PP_REPEAT_2_164(m, d) BOOST_PP_REPEAT_2_163(m, d) m(3, 163, d)
440
# define BOOST_PP_REPEAT_2_165(m, d) BOOST_PP_REPEAT_2_164(m, d) m(3, 164, d)
441
# define BOOST_PP_REPEAT_2_166(m, d) BOOST_PP_REPEAT_2_165(m, d) m(3, 165, d)
442
# define BOOST_PP_REPEAT_2_167(m, d) BOOST_PP_REPEAT_2_166(m, d) m(3, 166, d)
443
# define BOOST_PP_REPEAT_2_168(m, d) BOOST_PP_REPEAT_2_167(m, d) m(3, 167, d)
444
# define BOOST_PP_REPEAT_2_169(m, d) BOOST_PP_REPEAT_2_168(m, d) m(3, 168, d)
445
# define BOOST_PP_REPEAT_2_170(m, d) BOOST_PP_REPEAT_2_169(m, d) m(3, 169, d)
446
# define BOOST_PP_REPEAT_2_171(m, d) BOOST_PP_REPEAT_2_170(m, d) m(3, 170, d)
447
# define BOOST_PP_REPEAT_2_172(m, d) BOOST_PP_REPEAT_2_171(m, d) m(3, 171, d)
448
# define BOOST_PP_REPEAT_2_173(m, d) BOOST_PP_REPEAT_2_172(m, d) m(3, 172, d)
449
# define BOOST_PP_REPEAT_2_174(m, d) BOOST_PP_REPEAT_2_173(m, d) m(3, 173, d)
450
# define BOOST_PP_REPEAT_2_175(m, d) BOOST_PP_REPEAT_2_174(m, d) m(3, 174, d)
451
# define BOOST_PP_REPEAT_2_176(m, d) BOOST_PP_REPEAT_2_175(m, d) m(3, 175, d)
452
# define BOOST_PP_REPEAT_2_177(m, d) BOOST_PP_REPEAT_2_176(m, d) m(3, 176, d)
453
# define BOOST_PP_REPEAT_2_178(m, d) BOOST_PP_REPEAT_2_177(m, d) m(3, 177, d)
454
# define BOOST_PP_REPEAT_2_179(m, d) BOOST_PP_REPEAT_2_178(m, d) m(3, 178, d)
455
# define BOOST_PP_REPEAT_2_180(m, d) BOOST_PP_REPEAT_2_179(m, d) m(3, 179, d)
456
# define BOOST_PP_REPEAT_2_181(m, d) BOOST_PP_REPEAT_2_180(m, d) m(3, 180, d)
457
# define BOOST_PP_REPEAT_2_182(m, d) BOOST_PP_REPEAT_2_181(m, d) m(3, 181, d)
458
# define BOOST_PP_REPEAT_2_183(m, d) BOOST_PP_REPEAT_2_182(m, d) m(3, 182, d)
459
# define BOOST_PP_REPEAT_2_184(m, d) BOOST_PP_REPEAT_2_183(m, d) m(3, 183, d)
460
# define BOOST_PP_REPEAT_2_185(m, d) BOOST_PP_REPEAT_2_184(m, d) m(3, 184, d)
461
# define BOOST_PP_REPEAT_2_186(m, d) BOOST_PP_REPEAT_2_185(m, d) m(3, 185, d)
462
# define BOOST_PP_REPEAT_2_187(m, d) BOOST_PP_REPEAT_2_186(m, d) m(3, 186, d)
463
# define BOOST_PP_REPEAT_2_188(m, d) BOOST_PP_REPEAT_2_187(m, d) m(3, 187, d)
464
# define BOOST_PP_REPEAT_2_189(m, d) BOOST_PP_REPEAT_2_188(m, d) m(3, 188, d)
465
# define BOOST_PP_REPEAT_2_190(m, d) BOOST_PP_REPEAT_2_189(m, d) m(3, 189, d)
466
# define BOOST_PP_REPEAT_2_191(m, d) BOOST_PP_REPEAT_2_190(m, d) m(3, 190, d)
467
# define BOOST_PP_REPEAT_2_192(m, d) BOOST_PP_REPEAT_2_191(m, d) m(3, 191, d)
468
# define BOOST_PP_REPEAT_2_193(m, d) BOOST_PP_REPEAT_2_192(m, d) m(3, 192, d)
469
# define BOOST_PP_REPEAT_2_194(m, d) BOOST_PP_REPEAT_2_193(m, d) m(3, 193, d)
470
# define BOOST_PP_REPEAT_2_195(m, d) BOOST_PP_REPEAT_2_194(m, d) m(3, 194, d)
471
# define BOOST_PP_REPEAT_2_196(m, d) BOOST_PP_REPEAT_2_195(m, d) m(3, 195, d)
472
# define BOOST_PP_REPEAT_2_197(m, d) BOOST_PP_REPEAT_2_196(m, d) m(3, 196, d)
473
# define BOOST_PP_REPEAT_2_198(m, d) BOOST_PP_REPEAT_2_197(m, d) m(3, 197, d)
474
# define BOOST_PP_REPEAT_2_199(m, d) BOOST_PP_REPEAT_2_198(m, d) m(3, 198, d)
475
# define BOOST_PP_REPEAT_2_200(m, d) BOOST_PP_REPEAT_2_199(m, d) m(3, 199, d)
476
# define BOOST_PP_REPEAT_2_201(m, d) BOOST_PP_REPEAT_2_200(m, d) m(3, 200, d)
477
# define BOOST_PP_REPEAT_2_202(m, d) BOOST_PP_REPEAT_2_201(m, d) m(3, 201, d)
478
# define BOOST_PP_REPEAT_2_203(m, d) BOOST_PP_REPEAT_2_202(m, d) m(3, 202, d)
479
# define BOOST_PP_REPEAT_2_204(m, d) BOOST_PP_REPEAT_2_203(m, d) m(3, 203, d)
480
# define BOOST_PP_REPEAT_2_205(m, d) BOOST_PP_REPEAT_2_204(m, d) m(3, 204, d)
481
# define BOOST_PP_REPEAT_2_206(m, d) BOOST_PP_REPEAT_2_205(m, d) m(3, 205, d)
482
# define BOOST_PP_REPEAT_2_207(m, d) BOOST_PP_REPEAT_2_206(m, d) m(3, 206, d)
483
# define BOOST_PP_REPEAT_2_208(m, d) BOOST_PP_REPEAT_2_207(m, d) m(3, 207, d)
484
# define BOOST_PP_REPEAT_2_209(m, d) BOOST_PP_REPEAT_2_208(m, d) m(3, 208, d)
485
# define BOOST_PP_REPEAT_2_210(m, d) BOOST_PP_REPEAT_2_209(m, d) m(3, 209, d)
486
# define BOOST_PP_REPEAT_2_211(m, d) BOOST_PP_REPEAT_2_210(m, d) m(3, 210, d)
487
# define BOOST_PP_REPEAT_2_212(m, d) BOOST_PP_REPEAT_2_211(m, d) m(3, 211, d)
488
# define BOOST_PP_REPEAT_2_213(m, d) BOOST_PP_REPEAT_2_212(m, d) m(3, 212, d)
489
# define BOOST_PP_REPEAT_2_214(m, d) BOOST_PP_REPEAT_2_213(m, d) m(3, 213, d)
490
# define BOOST_PP_REPEAT_2_215(m, d) BOOST_PP_REPEAT_2_214(m, d) m(3, 214, d)
491
# define BOOST_PP_REPEAT_2_216(m, d) BOOST_PP_REPEAT_2_215(m, d) m(3, 215, d)
492
# define BOOST_PP_REPEAT_2_217(m, d) BOOST_PP_REPEAT_2_216(m, d) m(3, 216, d)
493
# define BOOST_PP_REPEAT_2_218(m, d) BOOST_PP_REPEAT_2_217(m, d) m(3, 217, d)
494
# define BOOST_PP_REPEAT_2_219(m, d) BOOST_PP_REPEAT_2_218(m, d) m(3, 218, d)
495
# define BOOST_PP_REPEAT_2_220(m, d) BOOST_PP_REPEAT_2_219(m, d) m(3, 219, d)
496
# define BOOST_PP_REPEAT_2_221(m, d) BOOST_PP_REPEAT_2_220(m, d) m(3, 220, d)
497
# define BOOST_PP_REPEAT_2_222(m, d) BOOST_PP_REPEAT_2_221(m, d) m(3, 221, d)
498
# define BOOST_PP_REPEAT_2_223(m, d) BOOST_PP_REPEAT_2_222(m, d) m(3, 222, d)
499
# define BOOST_PP_REPEAT_2_224(m, d) BOOST_PP_REPEAT_2_223(m, d) m(3, 223, d)
500
# define BOOST_PP_REPEAT_2_225(m, d) BOOST_PP_REPEAT_2_224(m, d) m(3, 224, d)
501
# define BOOST_PP_REPEAT_2_226(m, d) BOOST_PP_REPEAT_2_225(m, d) m(3, 225, d)
502
# define BOOST_PP_REPEAT_2_227(m, d) BOOST_PP_REPEAT_2_226(m, d) m(3, 226, d)
503
# define BOOST_PP_REPEAT_2_228(m, d) BOOST_PP_REPEAT_2_227(m, d) m(3, 227, d)
504
# define BOOST_PP_REPEAT_2_229(m, d) BOOST_PP_REPEAT_2_228(m, d) m(3, 228, d)
505
# define BOOST_PP_REPEAT_2_230(m, d) BOOST_PP_REPEAT_2_229(m, d) m(3, 229, d)
506
# define BOOST_PP_REPEAT_2_231(m, d) BOOST_PP_REPEAT_2_230(m, d) m(3, 230, d)
507
# define BOOST_PP_REPEAT_2_232(m, d) BOOST_PP_REPEAT_2_231(m, d) m(3, 231, d)
508
# define BOOST_PP_REPEAT_2_233(m, d) BOOST_PP_REPEAT_2_232(m, d) m(3, 232, d)
509
# define BOOST_PP_REPEAT_2_234(m, d) BOOST_PP_REPEAT_2_233(m, d) m(3, 233, d)
510
# define BOOST_PP_REPEAT_2_235(m, d) BOOST_PP_REPEAT_2_234(m, d) m(3, 234, d)
511
# define BOOST_PP_REPEAT_2_236(m, d) BOOST_PP_REPEAT_2_235(m, d) m(3, 235, d)
512
# define BOOST_PP_REPEAT_2_237(m, d) BOOST_PP_REPEAT_2_236(m, d) m(3, 236, d)
513
# define BOOST_PP_REPEAT_2_238(m, d) BOOST_PP_REPEAT_2_237(m, d) m(3, 237, d)
514
# define BOOST_PP_REPEAT_2_239(m, d) BOOST_PP_REPEAT_2_238(m, d) m(3, 238, d)
515
# define BOOST_PP_REPEAT_2_240(m, d) BOOST_PP_REPEAT_2_239(m, d) m(3, 239, d)
516
# define BOOST_PP_REPEAT_2_241(m, d) BOOST_PP_REPEAT_2_240(m, d) m(3, 240, d)
517
# define BOOST_PP_REPEAT_2_242(m, d) BOOST_PP_REPEAT_2_241(m, d) m(3, 241, d)
518
# define BOOST_PP_REPEAT_2_243(m, d) BOOST_PP_REPEAT_2_242(m, d) m(3, 242, d)
519
# define BOOST_PP_REPEAT_2_244(m, d) BOOST_PP_REPEAT_2_243(m, d) m(3, 243, d)
520
# define BOOST_PP_REPEAT_2_245(m, d) BOOST_PP_REPEAT_2_244(m, d) m(3, 244, d)
521
# define BOOST_PP_REPEAT_2_246(m, d) BOOST_PP_REPEAT_2_245(m, d) m(3, 245, d)
522
# define BOOST_PP_REPEAT_2_247(m, d) BOOST_PP_REPEAT_2_246(m, d) m(3, 246, d)
523
# define BOOST_PP_REPEAT_2_248(m, d) BOOST_PP_REPEAT_2_247(m, d) m(3, 247, d)
524
# define BOOST_PP_REPEAT_2_249(m, d) BOOST_PP_REPEAT_2_248(m, d) m(3, 248, d)
525
# define BOOST_PP_REPEAT_2_250(m, d) BOOST_PP_REPEAT_2_249(m, d) m(3, 249, d)
526
# define BOOST_PP_REPEAT_2_251(m, d) BOOST_PP_REPEAT_2_250(m, d) m(3, 250, d)
527
# define BOOST_PP_REPEAT_2_252(m, d) BOOST_PP_REPEAT_2_251(m, d) m(3, 251, d)
528
# define BOOST_PP_REPEAT_2_253(m, d) BOOST_PP_REPEAT_2_252(m, d) m(3, 252, d)
529
# define BOOST_PP_REPEAT_2_254(m, d) BOOST_PP_REPEAT_2_253(m, d) m(3, 253, d)
530
# define BOOST_PP_REPEAT_2_255(m, d) BOOST_PP_REPEAT_2_254(m, d) m(3, 254, d)
531
# define BOOST_PP_REPEAT_2_256(m, d) BOOST_PP_REPEAT_2_255(m, d) m(3, 255, d)
532
#
533
# define BOOST_PP_REPEAT_3_0(m, d)
534
# define BOOST_PP_REPEAT_3_1(m, d) m(4, 0, d)
535
# define BOOST_PP_REPEAT_3_2(m, d) BOOST_PP_REPEAT_3_1(m, d) m(4, 1, d)
536
# define BOOST_PP_REPEAT_3_3(m, d) BOOST_PP_REPEAT_3_2(m, d) m(4, 2, d)
537
# define BOOST_PP_REPEAT_3_4(m, d) BOOST_PP_REPEAT_3_3(m, d) m(4, 3, d)
538
# define BOOST_PP_REPEAT_3_5(m, d) BOOST_PP_REPEAT_3_4(m, d) m(4, 4, d)
539
# define BOOST_PP_REPEAT_3_6(m, d) BOOST_PP_REPEAT_3_5(m, d) m(4, 5, d)
540
# define BOOST_PP_REPEAT_3_7(m, d) BOOST_PP_REPEAT_3_6(m, d) m(4, 6, d)
541
# define BOOST_PP_REPEAT_3_8(m, d) BOOST_PP_REPEAT_3_7(m, d) m(4, 7, d)
542
# define BOOST_PP_REPEAT_3_9(m, d) BOOST_PP_REPEAT_3_8(m, d) m(4, 8, d)
543
# define BOOST_PP_REPEAT_3_10(m, d) BOOST_PP_REPEAT_3_9(m, d) m(4, 9, d)
544
# define BOOST_PP_REPEAT_3_11(m, d) BOOST_PP_REPEAT_3_10(m, d) m(4, 10, d)
545
# define BOOST_PP_REPEAT_3_12(m, d) BOOST_PP_REPEAT_3_11(m, d) m(4, 11, d)
546
# define BOOST_PP_REPEAT_3_13(m, d) BOOST_PP_REPEAT_3_12(m, d) m(4, 12, d)
547
# define BOOST_PP_REPEAT_3_14(m, d) BOOST_PP_REPEAT_3_13(m, d) m(4, 13, d)
548
# define BOOST_PP_REPEAT_3_15(m, d) BOOST_PP_REPEAT_3_14(m, d) m(4, 14, d)
549
# define BOOST_PP_REPEAT_3_16(m, d) BOOST_PP_REPEAT_3_15(m, d) m(4, 15, d)
550
# define BOOST_PP_REPEAT_3_17(m, d) BOOST_PP_REPEAT_3_16(m, d) m(4, 16, d)
551
# define BOOST_PP_REPEAT_3_18(m, d) BOOST_PP_REPEAT_3_17(m, d) m(4, 17, d)
552
# define BOOST_PP_REPEAT_3_19(m, d) BOOST_PP_REPEAT_3_18(m, d) m(4, 18, d)
553
# define BOOST_PP_REPEAT_3_20(m, d) BOOST_PP_REPEAT_3_19(m, d) m(4, 19, d)
554
# define BOOST_PP_REPEAT_3_21(m, d) BOOST_PP_REPEAT_3_20(m, d) m(4, 20, d)
555
# define BOOST_PP_REPEAT_3_22(m, d) BOOST_PP_REPEAT_3_21(m, d) m(4, 21, d)
556
# define BOOST_PP_REPEAT_3_23(m, d) BOOST_PP_REPEAT_3_22(m, d) m(4, 22, d)
557
# define BOOST_PP_REPEAT_3_24(m, d) BOOST_PP_REPEAT_3_23(m, d) m(4, 23, d)
558
# define BOOST_PP_REPEAT_3_25(m, d) BOOST_PP_REPEAT_3_24(m, d) m(4, 24, d)
559
# define BOOST_PP_REPEAT_3_26(m, d) BOOST_PP_REPEAT_3_25(m, d) m(4, 25, d)
560
# define BOOST_PP_REPEAT_3_27(m, d) BOOST_PP_REPEAT_3_26(m, d) m(4, 26, d)
561
# define BOOST_PP_REPEAT_3_28(m, d) BOOST_PP_REPEAT_3_27(m, d) m(4, 27, d)
562
# define BOOST_PP_REPEAT_3_29(m, d) BOOST_PP_REPEAT_3_28(m, d) m(4, 28, d)
563
# define BOOST_PP_REPEAT_3_30(m, d) BOOST_PP_REPEAT_3_29(m, d) m(4, 29, d)
564
# define BOOST_PP_REPEAT_3_31(m, d) BOOST_PP_REPEAT_3_30(m, d) m(4, 30, d)
565
# define BOOST_PP_REPEAT_3_32(m, d) BOOST_PP_REPEAT_3_31(m, d) m(4, 31, d)
566
# define BOOST_PP_REPEAT_3_33(m, d) BOOST_PP_REPEAT_3_32(m, d) m(4, 32, d)
567
# define BOOST_PP_REPEAT_3_34(m, d) BOOST_PP_REPEAT_3_33(m, d) m(4, 33, d)
568
# define BOOST_PP_REPEAT_3_35(m, d) BOOST_PP_REPEAT_3_34(m, d) m(4, 34, d)
569
# define BOOST_PP_REPEAT_3_36(m, d) BOOST_PP_REPEAT_3_35(m, d) m(4, 35, d)
570
# define BOOST_PP_REPEAT_3_37(m, d) BOOST_PP_REPEAT_3_36(m, d) m(4, 36, d)
571
# define BOOST_PP_REPEAT_3_38(m, d) BOOST_PP_REPEAT_3_37(m, d) m(4, 37, d)
572
# define BOOST_PP_REPEAT_3_39(m, d) BOOST_PP_REPEAT_3_38(m, d) m(4, 38, d)
573
# define BOOST_PP_REPEAT_3_40(m, d) BOOST_PP_REPEAT_3_39(m, d) m(4, 39, d)
574
# define BOOST_PP_REPEAT_3_41(m, d) BOOST_PP_REPEAT_3_40(m, d) m(4, 40, d)
575
# define BOOST_PP_REPEAT_3_42(m, d) BOOST_PP_REPEAT_3_41(m, d) m(4, 41, d)
576
# define BOOST_PP_REPEAT_3_43(m, d) BOOST_PP_REPEAT_3_42(m, d) m(4, 42, d)
577
# define BOOST_PP_REPEAT_3_44(m, d) BOOST_PP_REPEAT_3_43(m, d) m(4, 43, d)
578
# define BOOST_PP_REPEAT_3_45(m, d) BOOST_PP_REPEAT_3_44(m, d) m(4, 44, d)
579
# define BOOST_PP_REPEAT_3_46(m, d) BOOST_PP_REPEAT_3_45(m, d) m(4, 45, d)
580
# define BOOST_PP_REPEAT_3_47(m, d) BOOST_PP_REPEAT_3_46(m, d) m(4, 46, d)
581
# define BOOST_PP_REPEAT_3_48(m, d) BOOST_PP_REPEAT_3_47(m, d) m(4, 47, d)
582
# define BOOST_PP_REPEAT_3_49(m, d) BOOST_PP_REPEAT_3_48(m, d) m(4, 48, d)
583
# define BOOST_PP_REPEAT_3_50(m, d) BOOST_PP_REPEAT_3_49(m, d) m(4, 49, d)
584
# define BOOST_PP_REPEAT_3_51(m, d) BOOST_PP_REPEAT_3_50(m, d) m(4, 50, d)
585
# define BOOST_PP_REPEAT_3_52(m, d) BOOST_PP_REPEAT_3_51(m, d) m(4, 51, d)
586
# define BOOST_PP_REPEAT_3_53(m, d) BOOST_PP_REPEAT_3_52(m, d) m(4, 52, d)
587
# define BOOST_PP_REPEAT_3_54(m, d) BOOST_PP_REPEAT_3_53(m, d) m(4, 53, d)
588
# define BOOST_PP_REPEAT_3_55(m, d) BOOST_PP_REPEAT_3_54(m, d) m(4, 54, d)
589
# define BOOST_PP_REPEAT_3_56(m, d) BOOST_PP_REPEAT_3_55(m, d) m(4, 55, d)
590
# define BOOST_PP_REPEAT_3_57(m, d) BOOST_PP_REPEAT_3_56(m, d) m(4, 56, d)
591
# define BOOST_PP_REPEAT_3_58(m, d) BOOST_PP_REPEAT_3_57(m, d) m(4, 57, d)
592
# define BOOST_PP_REPEAT_3_59(m, d) BOOST_PP_REPEAT_3_58(m, d) m(4, 58, d)
593
# define BOOST_PP_REPEAT_3_60(m, d) BOOST_PP_REPEAT_3_59(m, d) m(4, 59, d)
594
# define BOOST_PP_REPEAT_3_61(m, d) BOOST_PP_REPEAT_3_60(m, d) m(4, 60, d)
595
# define BOOST_PP_REPEAT_3_62(m, d) BOOST_PP_REPEAT_3_61(m, d) m(4, 61, d)
596
# define BOOST_PP_REPEAT_3_63(m, d) BOOST_PP_REPEAT_3_62(m, d) m(4, 62, d)
597
# define BOOST_PP_REPEAT_3_64(m, d) BOOST_PP_REPEAT_3_63(m, d) m(4, 63, d)
598
# define BOOST_PP_REPEAT_3_65(m, d) BOOST_PP_REPEAT_3_64(m, d) m(4, 64, d)
599
# define BOOST_PP_REPEAT_3_66(m, d) BOOST_PP_REPEAT_3_65(m, d) m(4, 65, d)
600
# define BOOST_PP_REPEAT_3_67(m, d) BOOST_PP_REPEAT_3_66(m, d) m(4, 66, d)
601
# define BOOST_PP_REPEAT_3_68(m, d) BOOST_PP_REPEAT_3_67(m, d) m(4, 67, d)
602
# define BOOST_PP_REPEAT_3_69(m, d) BOOST_PP_REPEAT_3_68(m, d) m(4, 68, d)
603
# define BOOST_PP_REPEAT_3_70(m, d) BOOST_PP_REPEAT_3_69(m, d) m(4, 69, d)
604
# define BOOST_PP_REPEAT_3_71(m, d) BOOST_PP_REPEAT_3_70(m, d) m(4, 70, d)
605
# define BOOST_PP_REPEAT_3_72(m, d) BOOST_PP_REPEAT_3_71(m, d) m(4, 71, d)
606
# define BOOST_PP_REPEAT_3_73(m, d) BOOST_PP_REPEAT_3_72(m, d) m(4, 72, d)
607
# define BOOST_PP_REPEAT_3_74(m, d) BOOST_PP_REPEAT_3_73(m, d) m(4, 73, d)
608
# define BOOST_PP_REPEAT_3_75(m, d) BOOST_PP_REPEAT_3_74(m, d) m(4, 74, d)
609
# define BOOST_PP_REPEAT_3_76(m, d) BOOST_PP_REPEAT_3_75(m, d) m(4, 75, d)
610
# define BOOST_PP_REPEAT_3_77(m, d) BOOST_PP_REPEAT_3_76(m, d) m(4, 76, d)
611
# define BOOST_PP_REPEAT_3_78(m, d) BOOST_PP_REPEAT_3_77(m, d) m(4, 77, d)
612
# define BOOST_PP_REPEAT_3_79(m, d) BOOST_PP_REPEAT_3_78(m, d) m(4, 78, d)
613
# define BOOST_PP_REPEAT_3_80(m, d) BOOST_PP_REPEAT_3_79(m, d) m(4, 79, d)
614
# define BOOST_PP_REPEAT_3_81(m, d) BOOST_PP_REPEAT_3_80(m, d) m(4, 80, d)
615
# define BOOST_PP_REPEAT_3_82(m, d) BOOST_PP_REPEAT_3_81(m, d) m(4, 81, d)
616
# define BOOST_PP_REPEAT_3_83(m, d) BOOST_PP_REPEAT_3_82(m, d) m(4, 82, d)
617
# define BOOST_PP_REPEAT_3_84(m, d) BOOST_PP_REPEAT_3_83(m, d) m(4, 83, d)
618
# define BOOST_PP_REPEAT_3_85(m, d) BOOST_PP_REPEAT_3_84(m, d) m(4, 84, d)
619
# define BOOST_PP_REPEAT_3_86(m, d) BOOST_PP_REPEAT_3_85(m, d) m(4, 85, d)
620
# define BOOST_PP_REPEAT_3_87(m, d) BOOST_PP_REPEAT_3_86(m, d) m(4, 86, d)
621
# define BOOST_PP_REPEAT_3_88(m, d) BOOST_PP_REPEAT_3_87(m, d) m(4, 87, d)
622
# define BOOST_PP_REPEAT_3_89(m, d) BOOST_PP_REPEAT_3_88(m, d) m(4, 88, d)
623
# define BOOST_PP_REPEAT_3_90(m, d) BOOST_PP_REPEAT_3_89(m, d) m(4, 89, d)
624
# define BOOST_PP_REPEAT_3_91(m, d) BOOST_PP_REPEAT_3_90(m, d) m(4, 90, d)
625
# define BOOST_PP_REPEAT_3_92(m, d) BOOST_PP_REPEAT_3_91(m, d) m(4, 91, d)
626
# define BOOST_PP_REPEAT_3_93(m, d) BOOST_PP_REPEAT_3_92(m, d) m(4, 92, d)
627
# define BOOST_PP_REPEAT_3_94(m, d) BOOST_PP_REPEAT_3_93(m, d) m(4, 93, d)
628
# define BOOST_PP_REPEAT_3_95(m, d) BOOST_PP_REPEAT_3_94(m, d) m(4, 94, d)
629
# define BOOST_PP_REPEAT_3_96(m, d) BOOST_PP_REPEAT_3_95(m, d) m(4, 95, d)
630
# define BOOST_PP_REPEAT_3_97(m, d) BOOST_PP_REPEAT_3_96(m, d) m(4, 96, d)
631
# define BOOST_PP_REPEAT_3_98(m, d) BOOST_PP_REPEAT_3_97(m, d) m(4, 97, d)
632
# define BOOST_PP_REPEAT_3_99(m, d) BOOST_PP_REPEAT_3_98(m, d) m(4, 98, d)
633
# define BOOST_PP_REPEAT_3_100(m, d) BOOST_PP_REPEAT_3_99(m, d) m(4, 99, d)
634
# define BOOST_PP_REPEAT_3_101(m, d) BOOST_PP_REPEAT_3_100(m, d) m(4, 100, d)
635
# define BOOST_PP_REPEAT_3_102(m, d) BOOST_PP_REPEAT_3_101(m, d) m(4, 101, d)
636
# define BOOST_PP_REPEAT_3_103(m, d) BOOST_PP_REPEAT_3_102(m, d) m(4, 102, d)
637
# define BOOST_PP_REPEAT_3_104(m, d) BOOST_PP_REPEAT_3_103(m, d) m(4, 103, d)
638
# define BOOST_PP_REPEAT_3_105(m, d) BOOST_PP_REPEAT_3_104(m, d) m(4, 104, d)
639
# define BOOST_PP_REPEAT_3_106(m, d) BOOST_PP_REPEAT_3_105(m, d) m(4, 105, d)
640
# define BOOST_PP_REPEAT_3_107(m, d) BOOST_PP_REPEAT_3_106(m, d) m(4, 106, d)
641
# define BOOST_PP_REPEAT_3_108(m, d) BOOST_PP_REPEAT_3_107(m, d) m(4, 107, d)
642
# define BOOST_PP_REPEAT_3_109(m, d) BOOST_PP_REPEAT_3_108(m, d) m(4, 108, d)
643
# define BOOST_PP_REPEAT_3_110(m, d) BOOST_PP_REPEAT_3_109(m, d) m(4, 109, d)
644
# define BOOST_PP_REPEAT_3_111(m, d) BOOST_PP_REPEAT_3_110(m, d) m(4, 110, d)
645
# define BOOST_PP_REPEAT_3_112(m, d) BOOST_PP_REPEAT_3_111(m, d) m(4, 111, d)
646
# define BOOST_PP_REPEAT_3_113(m, d) BOOST_PP_REPEAT_3_112(m, d) m(4, 112, d)
647
# define BOOST_PP_REPEAT_3_114(m, d) BOOST_PP_REPEAT_3_113(m, d) m(4, 113, d)
648
# define BOOST_PP_REPEAT_3_115(m, d) BOOST_PP_REPEAT_3_114(m, d) m(4, 114, d)
649
# define BOOST_PP_REPEAT_3_116(m, d) BOOST_PP_REPEAT_3_115(m, d) m(4, 115, d)
650
# define BOOST_PP_REPEAT_3_117(m, d) BOOST_PP_REPEAT_3_116(m, d) m(4, 116, d)
651
# define BOOST_PP_REPEAT_3_118(m, d) BOOST_PP_REPEAT_3_117(m, d) m(4, 117, d)
652
# define BOOST_PP_REPEAT_3_119(m, d) BOOST_PP_REPEAT_3_118(m, d) m(4, 118, d)
653
# define BOOST_PP_REPEAT_3_120(m, d) BOOST_PP_REPEAT_3_119(m, d) m(4, 119, d)
654
# define BOOST_PP_REPEAT_3_121(m, d) BOOST_PP_REPEAT_3_120(m, d) m(4, 120, d)
655
# define BOOST_PP_REPEAT_3_122(m, d) BOOST_PP_REPEAT_3_121(m, d) m(4, 121, d)
656
# define BOOST_PP_REPEAT_3_123(m, d) BOOST_PP_REPEAT_3_122(m, d) m(4, 122, d)
657
# define BOOST_PP_REPEAT_3_124(m, d) BOOST_PP_REPEAT_3_123(m, d) m(4, 123, d)
658
# define BOOST_PP_REPEAT_3_125(m, d) BOOST_PP_REPEAT_3_124(m, d) m(4, 124, d)
659
# define BOOST_PP_REPEAT_3_126(m, d) BOOST_PP_REPEAT_3_125(m, d) m(4, 125, d)
660
# define BOOST_PP_REPEAT_3_127(m, d) BOOST_PP_REPEAT_3_126(m, d) m(4, 126, d)
661
# define BOOST_PP_REPEAT_3_128(m, d) BOOST_PP_REPEAT_3_127(m, d) m(4, 127, d)
662
# define BOOST_PP_REPEAT_3_129(m, d) BOOST_PP_REPEAT_3_128(m, d) m(4, 128, d)
663
# define BOOST_PP_REPEAT_3_130(m, d) BOOST_PP_REPEAT_3_129(m, d) m(4, 129, d)
664
# define BOOST_PP_REPEAT_3_131(m, d) BOOST_PP_REPEAT_3_130(m, d) m(4, 130, d)
665
# define BOOST_PP_REPEAT_3_132(m, d) BOOST_PP_REPEAT_3_131(m, d) m(4, 131, d)
666
# define BOOST_PP_REPEAT_3_133(m, d) BOOST_PP_REPEAT_3_132(m, d) m(4, 132, d)
667
# define BOOST_PP_REPEAT_3_134(m, d) BOOST_PP_REPEAT_3_133(m, d) m(4, 133, d)
668
# define BOOST_PP_REPEAT_3_135(m, d) BOOST_PP_REPEAT_3_134(m, d) m(4, 134, d)
669
# define BOOST_PP_REPEAT_3_136(m, d) BOOST_PP_REPEAT_3_135(m, d) m(4, 135, d)
670
# define BOOST_PP_REPEAT_3_137(m, d) BOOST_PP_REPEAT_3_136(m, d) m(4, 136, d)
671
# define BOOST_PP_REPEAT_3_138(m, d) BOOST_PP_REPEAT_3_137(m, d) m(4, 137, d)
672
# define BOOST_PP_REPEAT_3_139(m, d) BOOST_PP_REPEAT_3_138(m, d) m(4, 138, d)
673
# define BOOST_PP_REPEAT_3_140(m, d) BOOST_PP_REPEAT_3_139(m, d) m(4, 139, d)
674
# define BOOST_PP_REPEAT_3_141(m, d) BOOST_PP_REPEAT_3_140(m, d) m(4, 140, d)
675
# define BOOST_PP_REPEAT_3_142(m, d) BOOST_PP_REPEAT_3_141(m, d) m(4, 141, d)
676
# define BOOST_PP_REPEAT_3_143(m, d) BOOST_PP_REPEAT_3_142(m, d) m(4, 142, d)
677
# define BOOST_PP_REPEAT_3_144(m, d) BOOST_PP_REPEAT_3_143(m, d) m(4, 143, d)
678
# define BOOST_PP_REPEAT_3_145(m, d) BOOST_PP_REPEAT_3_144(m, d) m(4, 144, d)
679
# define BOOST_PP_REPEAT_3_146(m, d) BOOST_PP_REPEAT_3_145(m, d) m(4, 145, d)
680
# define BOOST_PP_REPEAT_3_147(m, d) BOOST_PP_REPEAT_3_146(m, d) m(4, 146, d)
681
# define BOOST_PP_REPEAT_3_148(m, d) BOOST_PP_REPEAT_3_147(m, d) m(4, 147, d)
682
# define BOOST_PP_REPEAT_3_149(m, d) BOOST_PP_REPEAT_3_148(m, d) m(4, 148, d)
683
# define BOOST_PP_REPEAT_3_150(m, d) BOOST_PP_REPEAT_3_149(m, d) m(4, 149, d)
684
# define BOOST_PP_REPEAT_3_151(m, d) BOOST_PP_REPEAT_3_150(m, d) m(4, 150, d)
685
# define BOOST_PP_REPEAT_3_152(m, d) BOOST_PP_REPEAT_3_151(m, d) m(4, 151, d)
686
# define BOOST_PP_REPEAT_3_153(m, d) BOOST_PP_REPEAT_3_152(m, d) m(4, 152, d)
687
# define BOOST_PP_REPEAT_3_154(m, d) BOOST_PP_REPEAT_3_153(m, d) m(4, 153, d)
688
# define BOOST_PP_REPEAT_3_155(m, d) BOOST_PP_REPEAT_3_154(m, d) m(4, 154, d)
689
# define BOOST_PP_REPEAT_3_156(m, d) BOOST_PP_REPEAT_3_155(m, d) m(4, 155, d)
690
# define BOOST_PP_REPEAT_3_157(m, d) BOOST_PP_REPEAT_3_156(m, d) m(4, 156, d)
691
# define BOOST_PP_REPEAT_3_158(m, d) BOOST_PP_REPEAT_3_157(m, d) m(4, 157, d)
692
# define BOOST_PP_REPEAT_3_159(m, d) BOOST_PP_REPEAT_3_158(m, d) m(4, 158, d)
693
# define BOOST_PP_REPEAT_3_160(m, d) BOOST_PP_REPEAT_3_159(m, d) m(4, 159, d)
694
# define BOOST_PP_REPEAT_3_161(m, d) BOOST_PP_REPEAT_3_160(m, d) m(4, 160, d)
695
# define BOOST_PP_REPEAT_3_162(m, d) BOOST_PP_REPEAT_3_161(m, d) m(4, 161, d)
696
# define BOOST_PP_REPEAT_3_163(m, d) BOOST_PP_REPEAT_3_162(m, d) m(4, 162, d)
697
# define BOOST_PP_REPEAT_3_164(m, d) BOOST_PP_REPEAT_3_163(m, d) m(4, 163, d)
698
# define BOOST_PP_REPEAT_3_165(m, d) BOOST_PP_REPEAT_3_164(m, d) m(4, 164, d)
699
# define BOOST_PP_REPEAT_3_166(m, d) BOOST_PP_REPEAT_3_165(m, d) m(4, 165, d)
700
# define BOOST_PP_REPEAT_3_167(m, d) BOOST_PP_REPEAT_3_166(m, d) m(4, 166, d)
701
# define BOOST_PP_REPEAT_3_168(m, d) BOOST_PP_REPEAT_3_167(m, d) m(4, 167, d)
702
# define BOOST_PP_REPEAT_3_169(m, d) BOOST_PP_REPEAT_3_168(m, d) m(4, 168, d)
703
# define BOOST_PP_REPEAT_3_170(m, d) BOOST_PP_REPEAT_3_169(m, d) m(4, 169, d)
704
# define BOOST_PP_REPEAT_3_171(m, d) BOOST_PP_REPEAT_3_170(m, d) m(4, 170, d)
705
# define BOOST_PP_REPEAT_3_172(m, d) BOOST_PP_REPEAT_3_171(m, d) m(4, 171, d)
706
# define BOOST_PP_REPEAT_3_173(m, d) BOOST_PP_REPEAT_3_172(m, d) m(4, 172, d)
707
# define BOOST_PP_REPEAT_3_174(m, d) BOOST_PP_REPEAT_3_173(m, d) m(4, 173, d)
708
# define BOOST_PP_REPEAT_3_175(m, d) BOOST_PP_REPEAT_3_174(m, d) m(4, 174, d)
709
# define BOOST_PP_REPEAT_3_176(m, d) BOOST_PP_REPEAT_3_175(m, d) m(4, 175, d)
710
# define BOOST_PP_REPEAT_3_177(m, d) BOOST_PP_REPEAT_3_176(m, d) m(4, 176, d)
711
# define BOOST_PP_REPEAT_3_178(m, d) BOOST_PP_REPEAT_3_177(m, d) m(4, 177, d)
712
# define BOOST_PP_REPEAT_3_179(m, d) BOOST_PP_REPEAT_3_178(m, d) m(4, 178, d)
713
# define BOOST_PP_REPEAT_3_180(m, d) BOOST_PP_REPEAT_3_179(m, d) m(4, 179, d)
714
# define BOOST_PP_REPEAT_3_181(m, d) BOOST_PP_REPEAT_3_180(m, d) m(4, 180, d)
715
# define BOOST_PP_REPEAT_3_182(m, d) BOOST_PP_REPEAT_3_181(m, d) m(4, 181, d)
716
# define BOOST_PP_REPEAT_3_183(m, d) BOOST_PP_REPEAT_3_182(m, d) m(4, 182, d)
717
# define BOOST_PP_REPEAT_3_184(m, d) BOOST_PP_REPEAT_3_183(m, d) m(4, 183, d)
718
# define BOOST_PP_REPEAT_3_185(m, d) BOOST_PP_REPEAT_3_184(m, d) m(4, 184, d)
719
# define BOOST_PP_REPEAT_3_186(m, d) BOOST_PP_REPEAT_3_185(m, d) m(4, 185, d)
720
# define BOOST_PP_REPEAT_3_187(m, d) BOOST_PP_REPEAT_3_186(m, d) m(4, 186, d)
721
# define BOOST_PP_REPEAT_3_188(m, d) BOOST_PP_REPEAT_3_187(m, d) m(4, 187, d)
722
# define BOOST_PP_REPEAT_3_189(m, d) BOOST_PP_REPEAT_3_188(m, d) m(4, 188, d)
723
# define BOOST_PP_REPEAT_3_190(m, d) BOOST_PP_REPEAT_3_189(m, d) m(4, 189, d)
724
# define BOOST_PP_REPEAT_3_191(m, d) BOOST_PP_REPEAT_3_190(m, d) m(4, 190, d)
725
# define BOOST_PP_REPEAT_3_192(m, d) BOOST_PP_REPEAT_3_191(m, d) m(4, 191, d)
726
# define BOOST_PP_REPEAT_3_193(m, d) BOOST_PP_REPEAT_3_192(m, d) m(4, 192, d)
727
# define BOOST_PP_REPEAT_3_194(m, d) BOOST_PP_REPEAT_3_193(m, d) m(4, 193, d)
728
# define BOOST_PP_REPEAT_3_195(m, d) BOOST_PP_REPEAT_3_194(m, d) m(4, 194, d)
729
# define BOOST_PP_REPEAT_3_196(m, d) BOOST_PP_REPEAT_3_195(m, d) m(4, 195, d)
730
# define BOOST_PP_REPEAT_3_197(m, d) BOOST_PP_REPEAT_3_196(m, d) m(4, 196, d)
731
# define BOOST_PP_REPEAT_3_198(m, d) BOOST_PP_REPEAT_3_197(m, d) m(4, 197, d)
732
# define BOOST_PP_REPEAT_3_199(m, d) BOOST_PP_REPEAT_3_198(m, d) m(4, 198, d)
733
# define BOOST_PP_REPEAT_3_200(m, d) BOOST_PP_REPEAT_3_199(m, d) m(4, 199, d)
734
# define BOOST_PP_REPEAT_3_201(m, d) BOOST_PP_REPEAT_3_200(m, d) m(4, 200, d)
735
# define BOOST_PP_REPEAT_3_202(m, d) BOOST_PP_REPEAT_3_201(m, d) m(4, 201, d)
736
# define BOOST_PP_REPEAT_3_203(m, d) BOOST_PP_REPEAT_3_202(m, d) m(4, 202, d)
737
# define BOOST_PP_REPEAT_3_204(m, d) BOOST_PP_REPEAT_3_203(m, d) m(4, 203, d)
738
# define BOOST_PP_REPEAT_3_205(m, d) BOOST_PP_REPEAT_3_204(m, d) m(4, 204, d)
739
# define BOOST_PP_REPEAT_3_206(m, d) BOOST_PP_REPEAT_3_205(m, d) m(4, 205, d)
740
# define BOOST_PP_REPEAT_3_207(m, d) BOOST_PP_REPEAT_3_206(m, d) m(4, 206, d)
741
# define BOOST_PP_REPEAT_3_208(m, d) BOOST_PP_REPEAT_3_207(m, d) m(4, 207, d)
742
# define BOOST_PP_REPEAT_3_209(m, d) BOOST_PP_REPEAT_3_208(m, d) m(4, 208, d)
743
# define BOOST_PP_REPEAT_3_210(m, d) BOOST_PP_REPEAT_3_209(m, d) m(4, 209, d)
744
# define BOOST_PP_REPEAT_3_211(m, d) BOOST_PP_REPEAT_3_210(m, d) m(4, 210, d)
745
# define BOOST_PP_REPEAT_3_212(m, d) BOOST_PP_REPEAT_3_211(m, d) m(4, 211, d)
746
# define BOOST_PP_REPEAT_3_213(m, d) BOOST_PP_REPEAT_3_212(m, d) m(4, 212, d)
747
# define BOOST_PP_REPEAT_3_214(m, d) BOOST_PP_REPEAT_3_213(m, d) m(4, 213, d)
748
# define BOOST_PP_REPEAT_3_215(m, d) BOOST_PP_REPEAT_3_214(m, d) m(4, 214, d)
749
# define BOOST_PP_REPEAT_3_216(m, d) BOOST_PP_REPEAT_3_215(m, d) m(4, 215, d)
750
# define BOOST_PP_REPEAT_3_217(m, d) BOOST_PP_REPEAT_3_216(m, d) m(4, 216, d)
751
# define BOOST_PP_REPEAT_3_218(m, d) BOOST_PP_REPEAT_3_217(m, d) m(4, 217, d)
752
# define BOOST_PP_REPEAT_3_219(m, d) BOOST_PP_REPEAT_3_218(m, d) m(4, 218, d)
753
# define BOOST_PP_REPEAT_3_220(m, d) BOOST_PP_REPEAT_3_219(m, d) m(4, 219, d)
754
# define BOOST_PP_REPEAT_3_221(m, d) BOOST_PP_REPEAT_3_220(m, d) m(4, 220, d)
755
# define BOOST_PP_REPEAT_3_222(m, d) BOOST_PP_REPEAT_3_221(m, d) m(4, 221, d)
756
# define BOOST_PP_REPEAT_3_223(m, d) BOOST_PP_REPEAT_3_222(m, d) m(4, 222, d)
757
# define BOOST_PP_REPEAT_3_224(m, d) BOOST_PP_REPEAT_3_223(m, d) m(4, 223, d)
758
# define BOOST_PP_REPEAT_3_225(m, d) BOOST_PP_REPEAT_3_224(m, d) m(4, 224, d)
759
# define BOOST_PP_REPEAT_3_226(m, d) BOOST_PP_REPEAT_3_225(m, d) m(4, 225, d)
760
# define BOOST_PP_REPEAT_3_227(m, d) BOOST_PP_REPEAT_3_226(m, d) m(4, 226, d)
761
# define BOOST_PP_REPEAT_3_228(m, d) BOOST_PP_REPEAT_3_227(m, d) m(4, 227, d)
762
# define BOOST_PP_REPEAT_3_229(m, d) BOOST_PP_REPEAT_3_228(m, d) m(4, 228, d)
763
# define BOOST_PP_REPEAT_3_230(m, d) BOOST_PP_REPEAT_3_229(m, d) m(4, 229, d)
764
# define BOOST_PP_REPEAT_3_231(m, d) BOOST_PP_REPEAT_3_230(m, d) m(4, 230, d)
765
# define BOOST_PP_REPEAT_3_232(m, d) BOOST_PP_REPEAT_3_231(m, d) m(4, 231, d)
766
# define BOOST_PP_REPEAT_3_233(m, d) BOOST_PP_REPEAT_3_232(m, d) m(4, 232, d)
767
# define BOOST_PP_REPEAT_3_234(m, d) BOOST_PP_REPEAT_3_233(m, d) m(4, 233, d)
768
# define BOOST_PP_REPEAT_3_235(m, d) BOOST_PP_REPEAT_3_234(m, d) m(4, 234, d)
769
# define BOOST_PP_REPEAT_3_236(m, d) BOOST_PP_REPEAT_3_235(m, d) m(4, 235, d)
770
# define BOOST_PP_REPEAT_3_237(m, d) BOOST_PP_REPEAT_3_236(m, d) m(4, 236, d)
771
# define BOOST_PP_REPEAT_3_238(m, d) BOOST_PP_REPEAT_3_237(m, d) m(4, 237, d)
772
# define BOOST_PP_REPEAT_3_239(m, d) BOOST_PP_REPEAT_3_238(m, d) m(4, 238, d)
773
# define BOOST_PP_REPEAT_3_240(m, d) BOOST_PP_REPEAT_3_239(m, d) m(4, 239, d)
774
# define BOOST_PP_REPEAT_3_241(m, d) BOOST_PP_REPEAT_3_240(m, d) m(4, 240, d)
775
# define BOOST_PP_REPEAT_3_242(m, d) BOOST_PP_REPEAT_3_241(m, d) m(4, 241, d)
776
# define BOOST_PP_REPEAT_3_243(m, d) BOOST_PP_REPEAT_3_242(m, d) m(4, 242, d)
777
# define BOOST_PP_REPEAT_3_244(m, d) BOOST_PP_REPEAT_3_243(m, d) m(4, 243, d)
778
# define BOOST_PP_REPEAT_3_245(m, d) BOOST_PP_REPEAT_3_244(m, d) m(4, 244, d)
779
# define BOOST_PP_REPEAT_3_246(m, d) BOOST_PP_REPEAT_3_245(m, d) m(4, 245, d)
780
# define BOOST_PP_REPEAT_3_247(m, d) BOOST_PP_REPEAT_3_246(m, d) m(4, 246, d)
781
# define BOOST_PP_REPEAT_3_248(m, d) BOOST_PP_REPEAT_3_247(m, d) m(4, 247, d)
782
# define BOOST_PP_REPEAT_3_249(m, d) BOOST_PP_REPEAT_3_248(m, d) m(4, 248, d)
783
# define BOOST_PP_REPEAT_3_250(m, d) BOOST_PP_REPEAT_3_249(m, d) m(4, 249, d)
784
# define BOOST_PP_REPEAT_3_251(m, d) BOOST_PP_REPEAT_3_250(m, d) m(4, 250, d)
785
# define BOOST_PP_REPEAT_3_252(m, d) BOOST_PP_REPEAT_3_251(m, d) m(4, 251, d)
786
# define BOOST_PP_REPEAT_3_253(m, d) BOOST_PP_REPEAT_3_252(m, d) m(4, 252, d)
787
# define BOOST_PP_REPEAT_3_254(m, d) BOOST_PP_REPEAT_3_253(m, d) m(4, 253, d)
788
# define BOOST_PP_REPEAT_3_255(m, d) BOOST_PP_REPEAT_3_254(m, d) m(4, 254, d)
789
# define BOOST_PP_REPEAT_3_256(m, d) BOOST_PP_REPEAT_3_255(m, d) m(4, 255, d)
790
#
791
# endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/preprocessor/repetition/repeat.hpp
Line
Count
Source
1
# /* Copyright (C) 2001
2
#  * Housemarque Oy
3
#  * http://www.housemarque.com
4
#  *
5
#  * Distributed under the Boost Software License, Version 1.0. (See
6
#  * accompanying file LICENSE_1_0.txt or copy at
7
#  * http://www.boost.org/LICENSE_1_0.txt)
8
#  */
9
#
10
# /* Revised by Paul Mensonides (2002) */
11
# /* Revised by Edward Diener (2020) */
12
#
13
# /* See http://www.boost.org for most recent version. */
14
#
15
# ifndef BOOST_PREPROCESSOR_REPETITION_REPEAT_HPP
16
# define BOOST_PREPROCESSOR_REPETITION_REPEAT_HPP
17
#
18
# include <boost/preprocessor/cat.hpp>
19
# include <boost/preprocessor/config/config.hpp>
20
# include <boost/preprocessor/debug/error.hpp>
21
# include <boost/preprocessor/detail/auto_rec.hpp>
22
# include <boost/preprocessor/tuple/eat.hpp>
23
#
24
# /* BOOST_PP_REPEAT */
25
#
26
# if 0
27
#    define BOOST_PP_REPEAT(count, macro, data)
28
# endif
29
#
30
# define BOOST_PP_REPEAT BOOST_PP_CAT(BOOST_PP_REPEAT_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
31
#
32
# define BOOST_PP_REPEAT_P(n) BOOST_PP_CAT(BOOST_PP_REPEAT_CHECK_, BOOST_PP_REPEAT_ ## n(1, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3, BOOST_PP_NIL))
33
#
34
# define BOOST_PP_REPEAT_CHECK_BOOST_PP_NIL 1
35
# define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_1(c, m, d) 0
36
# define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_2(c, m, d) 0
37
# define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_3(c, m, d) 0
38
#
39
120
# define BOOST_PP_REPEAT_1(c, m, d) BOOST_PP_REPEAT_1_I(c, m, d)
40
# define BOOST_PP_REPEAT_2(c, m, d) BOOST_PP_REPEAT_2_I(c, m, d)
41
# define BOOST_PP_REPEAT_3(c, m, d) BOOST_PP_REPEAT_3_I(c, m, d)
42
# define BOOST_PP_REPEAT_4(c, m, d) BOOST_PP_ERROR(0x0003)
43
#
44
120
# define BOOST_PP_REPEAT_1_I(c, m, d) BOOST_PP_REPEAT_1_ ## c(m, d)
45
# define BOOST_PP_REPEAT_2_I(c, m, d) BOOST_PP_REPEAT_2_ ## c(m, d)
46
# define BOOST_PP_REPEAT_3_I(c, m, d) BOOST_PP_REPEAT_3_ ## c(m, d)
47
#
48
# define BOOST_PP_REPEAT_1ST BOOST_PP_REPEAT_1
49
# define BOOST_PP_REPEAT_2ND BOOST_PP_REPEAT_2
50
# define BOOST_PP_REPEAT_3RD BOOST_PP_REPEAT_3
51
#
52
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
53
#
54
# define BOOST_PP_REPEAT_1_0(m, d)
55
# define BOOST_PP_REPEAT_1_1(m, d) m(2, 0, d)
56
# define BOOST_PP_REPEAT_1_2(m, d) BOOST_PP_REPEAT_1_1(m, d) m(2, 1, d)
57
# define BOOST_PP_REPEAT_1_3(m, d) BOOST_PP_REPEAT_1_2(m, d) m(2, 2, d)
58
# define BOOST_PP_REPEAT_1_4(m, d) BOOST_PP_REPEAT_1_3(m, d) m(2, 3, d)
59
# define BOOST_PP_REPEAT_1_5(m, d) BOOST_PP_REPEAT_1_4(m, d) m(2, 4, d)
60
# define BOOST_PP_REPEAT_1_6(m, d) BOOST_PP_REPEAT_1_5(m, d) m(2, 5, d)
61
# define BOOST_PP_REPEAT_1_7(m, d) BOOST_PP_REPEAT_1_6(m, d) m(2, 6, d)
62
# define BOOST_PP_REPEAT_1_8(m, d) BOOST_PP_REPEAT_1_7(m, d) m(2, 7, d)
63
# define BOOST_PP_REPEAT_1_9(m, d) BOOST_PP_REPEAT_1_8(m, d) m(2, 8, d)
64
# define BOOST_PP_REPEAT_1_10(m, d) BOOST_PP_REPEAT_1_9(m, d) m(2, 9, d)
65
# define BOOST_PP_REPEAT_1_11(m, d) BOOST_PP_REPEAT_1_10(m, d) m(2, 10, d)
66
# define BOOST_PP_REPEAT_1_12(m, d) BOOST_PP_REPEAT_1_11(m, d) m(2, 11, d)
67
# define BOOST_PP_REPEAT_1_13(m, d) BOOST_PP_REPEAT_1_12(m, d) m(2, 12, d)
68
# define BOOST_PP_REPEAT_1_14(m, d) BOOST_PP_REPEAT_1_13(m, d) m(2, 13, d)
69
# define BOOST_PP_REPEAT_1_15(m, d) BOOST_PP_REPEAT_1_14(m, d) m(2, 14, d)
70
# define BOOST_PP_REPEAT_1_16(m, d) BOOST_PP_REPEAT_1_15(m, d) m(2, 15, d)
71
# define BOOST_PP_REPEAT_1_17(m, d) BOOST_PP_REPEAT_1_16(m, d) m(2, 16, d)
72
# define BOOST_PP_REPEAT_1_18(m, d) BOOST_PP_REPEAT_1_17(m, d) m(2, 17, d)
73
# define BOOST_PP_REPEAT_1_19(m, d) BOOST_PP_REPEAT_1_18(m, d) m(2, 18, d)
74
# define BOOST_PP_REPEAT_1_20(m, d) BOOST_PP_REPEAT_1_19(m, d) m(2, 19, d)
75
# define BOOST_PP_REPEAT_1_21(m, d) BOOST_PP_REPEAT_1_20(m, d) m(2, 20, d)
76
# define BOOST_PP_REPEAT_1_22(m, d) BOOST_PP_REPEAT_1_21(m, d) m(2, 21, d)
77
# define BOOST_PP_REPEAT_1_23(m, d) BOOST_PP_REPEAT_1_22(m, d) m(2, 22, d)
78
# define BOOST_PP_REPEAT_1_24(m, d) BOOST_PP_REPEAT_1_23(m, d) m(2, 23, d)
79
# define BOOST_PP_REPEAT_1_25(m, d) BOOST_PP_REPEAT_1_24(m, d) m(2, 24, d)
80
# define BOOST_PP_REPEAT_1_26(m, d) BOOST_PP_REPEAT_1_25(m, d) m(2, 25, d)
81
# define BOOST_PP_REPEAT_1_27(m, d) BOOST_PP_REPEAT_1_26(m, d) m(2, 26, d)
82
# define BOOST_PP_REPEAT_1_28(m, d) BOOST_PP_REPEAT_1_27(m, d) m(2, 27, d)
83
# define BOOST_PP_REPEAT_1_29(m, d) BOOST_PP_REPEAT_1_28(m, d) m(2, 28, d)
84
# define BOOST_PP_REPEAT_1_30(m, d) BOOST_PP_REPEAT_1_29(m, d) m(2, 29, d)
85
# define BOOST_PP_REPEAT_1_31(m, d) BOOST_PP_REPEAT_1_30(m, d) m(2, 30, d)
86
# define BOOST_PP_REPEAT_1_32(m, d) BOOST_PP_REPEAT_1_31(m, d) m(2, 31, d)
87
# define BOOST_PP_REPEAT_1_33(m, d) BOOST_PP_REPEAT_1_32(m, d) m(2, 32, d)
88
# define BOOST_PP_REPEAT_1_34(m, d) BOOST_PP_REPEAT_1_33(m, d) m(2, 33, d)
89
# define BOOST_PP_REPEAT_1_35(m, d) BOOST_PP_REPEAT_1_34(m, d) m(2, 34, d)
90
# define BOOST_PP_REPEAT_1_36(m, d) BOOST_PP_REPEAT_1_35(m, d) m(2, 35, d)
91
# define BOOST_PP_REPEAT_1_37(m, d) BOOST_PP_REPEAT_1_36(m, d) m(2, 36, d)
92
# define BOOST_PP_REPEAT_1_38(m, d) BOOST_PP_REPEAT_1_37(m, d) m(2, 37, d)
93
# define BOOST_PP_REPEAT_1_39(m, d) BOOST_PP_REPEAT_1_38(m, d) m(2, 38, d)
94
# define BOOST_PP_REPEAT_1_40(m, d) BOOST_PP_REPEAT_1_39(m, d) m(2, 39, d)
95
# define BOOST_PP_REPEAT_1_41(m, d) BOOST_PP_REPEAT_1_40(m, d) m(2, 40, d)
96
# define BOOST_PP_REPEAT_1_42(m, d) BOOST_PP_REPEAT_1_41(m, d) m(2, 41, d)
97
# define BOOST_PP_REPEAT_1_43(m, d) BOOST_PP_REPEAT_1_42(m, d) m(2, 42, d)
98
# define BOOST_PP_REPEAT_1_44(m, d) BOOST_PP_REPEAT_1_43(m, d) m(2, 43, d)
99
# define BOOST_PP_REPEAT_1_45(m, d) BOOST_PP_REPEAT_1_44(m, d) m(2, 44, d)
100
# define BOOST_PP_REPEAT_1_46(m, d) BOOST_PP_REPEAT_1_45(m, d) m(2, 45, d)
101
# define BOOST_PP_REPEAT_1_47(m, d) BOOST_PP_REPEAT_1_46(m, d) m(2, 46, d)
102
# define BOOST_PP_REPEAT_1_48(m, d) BOOST_PP_REPEAT_1_47(m, d) m(2, 47, d)
103
# define BOOST_PP_REPEAT_1_49(m, d) BOOST_PP_REPEAT_1_48(m, d) m(2, 48, d)
104
# define BOOST_PP_REPEAT_1_50(m, d) BOOST_PP_REPEAT_1_49(m, d) m(2, 49, d)
105
# define BOOST_PP_REPEAT_1_51(m, d) BOOST_PP_REPEAT_1_50(m, d) m(2, 50, d)
106
# define BOOST_PP_REPEAT_1_52(m, d) BOOST_PP_REPEAT_1_51(m, d) m(2, 51, d)
107
# define BOOST_PP_REPEAT_1_53(m, d) BOOST_PP_REPEAT_1_52(m, d) m(2, 52, d)
108
# define BOOST_PP_REPEAT_1_54(m, d) BOOST_PP_REPEAT_1_53(m, d) m(2, 53, d)
109
# define BOOST_PP_REPEAT_1_55(m, d) BOOST_PP_REPEAT_1_54(m, d) m(2, 54, d)
110
# define BOOST_PP_REPEAT_1_56(m, d) BOOST_PP_REPEAT_1_55(m, d) m(2, 55, d)
111
# define BOOST_PP_REPEAT_1_57(m, d) BOOST_PP_REPEAT_1_56(m, d) m(2, 56, d)
112
# define BOOST_PP_REPEAT_1_58(m, d) BOOST_PP_REPEAT_1_57(m, d) m(2, 57, d)
113
# define BOOST_PP_REPEAT_1_59(m, d) BOOST_PP_REPEAT_1_58(m, d) m(2, 58, d)
114
# define BOOST_PP_REPEAT_1_60(m, d) BOOST_PP_REPEAT_1_59(m, d) m(2, 59, d)
115
# define BOOST_PP_REPEAT_1_61(m, d) BOOST_PP_REPEAT_1_60(m, d) m(2, 60, d)
116
# define BOOST_PP_REPEAT_1_62(m, d) BOOST_PP_REPEAT_1_61(m, d) m(2, 61, d)
117
# define BOOST_PP_REPEAT_1_63(m, d) BOOST_PP_REPEAT_1_62(m, d) m(2, 62, d)
118
# define BOOST_PP_REPEAT_1_64(m, d) BOOST_PP_REPEAT_1_63(m, d) m(2, 63, d)
119
# define BOOST_PP_REPEAT_1_65(m, d) BOOST_PP_REPEAT_1_64(m, d) m(2, 64, d)
120
# define BOOST_PP_REPEAT_1_66(m, d) BOOST_PP_REPEAT_1_65(m, d) m(2, 65, d)
121
# define BOOST_PP_REPEAT_1_67(m, d) BOOST_PP_REPEAT_1_66(m, d) m(2, 66, d)
122
# define BOOST_PP_REPEAT_1_68(m, d) BOOST_PP_REPEAT_1_67(m, d) m(2, 67, d)
123
# define BOOST_PP_REPEAT_1_69(m, d) BOOST_PP_REPEAT_1_68(m, d) m(2, 68, d)
124
# define BOOST_PP_REPEAT_1_70(m, d) BOOST_PP_REPEAT_1_69(m, d) m(2, 69, d)
125
# define BOOST_PP_REPEAT_1_71(m, d) BOOST_PP_REPEAT_1_70(m, d) m(2, 70, d)
126
# define BOOST_PP_REPEAT_1_72(m, d) BOOST_PP_REPEAT_1_71(m, d) m(2, 71, d)
127
# define BOOST_PP_REPEAT_1_73(m, d) BOOST_PP_REPEAT_1_72(m, d) m(2, 72, d)
128
# define BOOST_PP_REPEAT_1_74(m, d) BOOST_PP_REPEAT_1_73(m, d) m(2, 73, d)
129
# define BOOST_PP_REPEAT_1_75(m, d) BOOST_PP_REPEAT_1_74(m, d) m(2, 74, d)
130
# define BOOST_PP_REPEAT_1_76(m, d) BOOST_PP_REPEAT_1_75(m, d) m(2, 75, d)
131
# define BOOST_PP_REPEAT_1_77(m, d) BOOST_PP_REPEAT_1_76(m, d) m(2, 76, d)
132
# define BOOST_PP_REPEAT_1_78(m, d) BOOST_PP_REPEAT_1_77(m, d) m(2, 77, d)
133
# define BOOST_PP_REPEAT_1_79(m, d) BOOST_PP_REPEAT_1_78(m, d) m(2, 78, d)
134
# define BOOST_PP_REPEAT_1_80(m, d) BOOST_PP_REPEAT_1_79(m, d) m(2, 79, d)
135
# define BOOST_PP_REPEAT_1_81(m, d) BOOST_PP_REPEAT_1_80(m, d) m(2, 80, d)
136
# define BOOST_PP_REPEAT_1_82(m, d) BOOST_PP_REPEAT_1_81(m, d) m(2, 81, d)
137
# define BOOST_PP_REPEAT_1_83(m, d) BOOST_PP_REPEAT_1_82(m, d) m(2, 82, d)
138
# define BOOST_PP_REPEAT_1_84(m, d) BOOST_PP_REPEAT_1_83(m, d) m(2, 83, d)
139
# define BOOST_PP_REPEAT_1_85(m, d) BOOST_PP_REPEAT_1_84(m, d) m(2, 84, d)
140
# define BOOST_PP_REPEAT_1_86(m, d) BOOST_PP_REPEAT_1_85(m, d) m(2, 85, d)
141
# define BOOST_PP_REPEAT_1_87(m, d) BOOST_PP_REPEAT_1_86(m, d) m(2, 86, d)
142
# define BOOST_PP_REPEAT_1_88(m, d) BOOST_PP_REPEAT_1_87(m, d) m(2, 87, d)
143
# define BOOST_PP_REPEAT_1_89(m, d) BOOST_PP_REPEAT_1_88(m, d) m(2, 88, d)
144
# define BOOST_PP_REPEAT_1_90(m, d) BOOST_PP_REPEAT_1_89(m, d) m(2, 89, d)
145
# define BOOST_PP_REPEAT_1_91(m, d) BOOST_PP_REPEAT_1_90(m, d) m(2, 90, d)
146
# define BOOST_PP_REPEAT_1_92(m, d) BOOST_PP_REPEAT_1_91(m, d) m(2, 91, d)
147
# define BOOST_PP_REPEAT_1_93(m, d) BOOST_PP_REPEAT_1_92(m, d) m(2, 92, d)
148
# define BOOST_PP_REPEAT_1_94(m, d) BOOST_PP_REPEAT_1_93(m, d) m(2, 93, d)
149
# define BOOST_PP_REPEAT_1_95(m, d) BOOST_PP_REPEAT_1_94(m, d) m(2, 94, d)
150
# define BOOST_PP_REPEAT_1_96(m, d) BOOST_PP_REPEAT_1_95(m, d) m(2, 95, d)
151
# define BOOST_PP_REPEAT_1_97(m, d) BOOST_PP_REPEAT_1_96(m, d) m(2, 96, d)
152
# define BOOST_PP_REPEAT_1_98(m, d) BOOST_PP_REPEAT_1_97(m, d) m(2, 97, d)
153
# define BOOST_PP_REPEAT_1_99(m, d) BOOST_PP_REPEAT_1_98(m, d) m(2, 98, d)
154
# define BOOST_PP_REPEAT_1_100(m, d) BOOST_PP_REPEAT_1_99(m, d) m(2, 99, d)
155
# define BOOST_PP_REPEAT_1_101(m, d) BOOST_PP_REPEAT_1_100(m, d) m(2, 100, d)
156
# define BOOST_PP_REPEAT_1_102(m, d) BOOST_PP_REPEAT_1_101(m, d) m(2, 101, d)
157
# define BOOST_PP_REPEAT_1_103(m, d) BOOST_PP_REPEAT_1_102(m, d) m(2, 102, d)
158
# define BOOST_PP_REPEAT_1_104(m, d) BOOST_PP_REPEAT_1_103(m, d) m(2, 103, d)
159
# define BOOST_PP_REPEAT_1_105(m, d) BOOST_PP_REPEAT_1_104(m, d) m(2, 104, d)
160
# define BOOST_PP_REPEAT_1_106(m, d) BOOST_PP_REPEAT_1_105(m, d) m(2, 105, d)
161
# define BOOST_PP_REPEAT_1_107(m, d) BOOST_PP_REPEAT_1_106(m, d) m(2, 106, d)
162
# define BOOST_PP_REPEAT_1_108(m, d) BOOST_PP_REPEAT_1_107(m, d) m(2, 107, d)
163
# define BOOST_PP_REPEAT_1_109(m, d) BOOST_PP_REPEAT_1_108(m, d) m(2, 108, d)
164
# define BOOST_PP_REPEAT_1_110(m, d) BOOST_PP_REPEAT_1_109(m, d) m(2, 109, d)
165
# define BOOST_PP_REPEAT_1_111(m, d) BOOST_PP_REPEAT_1_110(m, d) m(2, 110, d)
166
# define BOOST_PP_REPEAT_1_112(m, d) BOOST_PP_REPEAT_1_111(m, d) m(2, 111, d)
167
# define BOOST_PP_REPEAT_1_113(m, d) BOOST_PP_REPEAT_1_112(m, d) m(2, 112, d)
168
# define BOOST_PP_REPEAT_1_114(m, d) BOOST_PP_REPEAT_1_113(m, d) m(2, 113, d)
169
# define BOOST_PP_REPEAT_1_115(m, d) BOOST_PP_REPEAT_1_114(m, d) m(2, 114, d)
170
# define BOOST_PP_REPEAT_1_116(m, d) BOOST_PP_REPEAT_1_115(m, d) m(2, 115, d)
171
# define BOOST_PP_REPEAT_1_117(m, d) BOOST_PP_REPEAT_1_116(m, d) m(2, 116, d)
172
# define BOOST_PP_REPEAT_1_118(m, d) BOOST_PP_REPEAT_1_117(m, d) m(2, 117, d)
173
# define BOOST_PP_REPEAT_1_119(m, d) BOOST_PP_REPEAT_1_118(m, d) m(2, 118, d)
174
# define BOOST_PP_REPEAT_1_120(m, d) BOOST_PP_REPEAT_1_119(m, d) m(2, 119, d)
175
# define BOOST_PP_REPEAT_1_121(m, d) BOOST_PP_REPEAT_1_120(m, d) m(2, 120, d)
176
# define BOOST_PP_REPEAT_1_122(m, d) BOOST_PP_REPEAT_1_121(m, d) m(2, 121, d)
177
# define BOOST_PP_REPEAT_1_123(m, d) BOOST_PP_REPEAT_1_122(m, d) m(2, 122, d)
178
# define BOOST_PP_REPEAT_1_124(m, d) BOOST_PP_REPEAT_1_123(m, d) m(2, 123, d)
179
# define BOOST_PP_REPEAT_1_125(m, d) BOOST_PP_REPEAT_1_124(m, d) m(2, 124, d)
180
# define BOOST_PP_REPEAT_1_126(m, d) BOOST_PP_REPEAT_1_125(m, d) m(2, 125, d)
181
# define BOOST_PP_REPEAT_1_127(m, d) BOOST_PP_REPEAT_1_126(m, d) m(2, 126, d)
182
# define BOOST_PP_REPEAT_1_128(m, d) BOOST_PP_REPEAT_1_127(m, d) m(2, 127, d)
183
# define BOOST_PP_REPEAT_1_129(m, d) BOOST_PP_REPEAT_1_128(m, d) m(2, 128, d)
184
# define BOOST_PP_REPEAT_1_130(m, d) BOOST_PP_REPEAT_1_129(m, d) m(2, 129, d)
185
# define BOOST_PP_REPEAT_1_131(m, d) BOOST_PP_REPEAT_1_130(m, d) m(2, 130, d)
186
# define BOOST_PP_REPEAT_1_132(m, d) BOOST_PP_REPEAT_1_131(m, d) m(2, 131, d)
187
# define BOOST_PP_REPEAT_1_133(m, d) BOOST_PP_REPEAT_1_132(m, d) m(2, 132, d)
188
# define BOOST_PP_REPEAT_1_134(m, d) BOOST_PP_REPEAT_1_133(m, d) m(2, 133, d)
189
# define BOOST_PP_REPEAT_1_135(m, d) BOOST_PP_REPEAT_1_134(m, d) m(2, 134, d)
190
# define BOOST_PP_REPEAT_1_136(m, d) BOOST_PP_REPEAT_1_135(m, d) m(2, 135, d)
191
# define BOOST_PP_REPEAT_1_137(m, d) BOOST_PP_REPEAT_1_136(m, d) m(2, 136, d)
192
# define BOOST_PP_REPEAT_1_138(m, d) BOOST_PP_REPEAT_1_137(m, d) m(2, 137, d)
193
# define BOOST_PP_REPEAT_1_139(m, d) BOOST_PP_REPEAT_1_138(m, d) m(2, 138, d)
194
# define BOOST_PP_REPEAT_1_140(m, d) BOOST_PP_REPEAT_1_139(m, d) m(2, 139, d)
195
# define BOOST_PP_REPEAT_1_141(m, d) BOOST_PP_REPEAT_1_140(m, d) m(2, 140, d)
196
# define BOOST_PP_REPEAT_1_142(m, d) BOOST_PP_REPEAT_1_141(m, d) m(2, 141, d)
197
# define BOOST_PP_REPEAT_1_143(m, d) BOOST_PP_REPEAT_1_142(m, d) m(2, 142, d)
198
# define BOOST_PP_REPEAT_1_144(m, d) BOOST_PP_REPEAT_1_143(m, d) m(2, 143, d)
199
# define BOOST_PP_REPEAT_1_145(m, d) BOOST_PP_REPEAT_1_144(m, d) m(2, 144, d)
200
# define BOOST_PP_REPEAT_1_146(m, d) BOOST_PP_REPEAT_1_145(m, d) m(2, 145, d)
201
# define BOOST_PP_REPEAT_1_147(m, d) BOOST_PP_REPEAT_1_146(m, d) m(2, 146, d)
202
# define BOOST_PP_REPEAT_1_148(m, d) BOOST_PP_REPEAT_1_147(m, d) m(2, 147, d)
203
# define BOOST_PP_REPEAT_1_149(m, d) BOOST_PP_REPEAT_1_148(m, d) m(2, 148, d)
204
# define BOOST_PP_REPEAT_1_150(m, d) BOOST_PP_REPEAT_1_149(m, d) m(2, 149, d)
205
# define BOOST_PP_REPEAT_1_151(m, d) BOOST_PP_REPEAT_1_150(m, d) m(2, 150, d)
206
# define BOOST_PP_REPEAT_1_152(m, d) BOOST_PP_REPEAT_1_151(m, d) m(2, 151, d)
207
# define BOOST_PP_REPEAT_1_153(m, d) BOOST_PP_REPEAT_1_152(m, d) m(2, 152, d)
208
# define BOOST_PP_REPEAT_1_154(m, d) BOOST_PP_REPEAT_1_153(m, d) m(2, 153, d)
209
# define BOOST_PP_REPEAT_1_155(m, d) BOOST_PP_REPEAT_1_154(m, d) m(2, 154, d)
210
# define BOOST_PP_REPEAT_1_156(m, d) BOOST_PP_REPEAT_1_155(m, d) m(2, 155, d)
211
# define BOOST_PP_REPEAT_1_157(m, d) BOOST_PP_REPEAT_1_156(m, d) m(2, 156, d)
212
# define BOOST_PP_REPEAT_1_158(m, d) BOOST_PP_REPEAT_1_157(m, d) m(2, 157, d)
213
# define BOOST_PP_REPEAT_1_159(m, d) BOOST_PP_REPEAT_1_158(m, d) m(2, 158, d)
214
# define BOOST_PP_REPEAT_1_160(m, d) BOOST_PP_REPEAT_1_159(m, d) m(2, 159, d)
215
# define BOOST_PP_REPEAT_1_161(m, d) BOOST_PP_REPEAT_1_160(m, d) m(2, 160, d)
216
# define BOOST_PP_REPEAT_1_162(m, d) BOOST_PP_REPEAT_1_161(m, d) m(2, 161, d)
217
# define BOOST_PP_REPEAT_1_163(m, d) BOOST_PP_REPEAT_1_162(m, d) m(2, 162, d)
218
# define BOOST_PP_REPEAT_1_164(m, d) BOOST_PP_REPEAT_1_163(m, d) m(2, 163, d)
219
# define BOOST_PP_REPEAT_1_165(m, d) BOOST_PP_REPEAT_1_164(m, d) m(2, 164, d)
220
# define BOOST_PP_REPEAT_1_166(m, d) BOOST_PP_REPEAT_1_165(m, d) m(2, 165, d)
221
# define BOOST_PP_REPEAT_1_167(m, d) BOOST_PP_REPEAT_1_166(m, d) m(2, 166, d)
222
# define BOOST_PP_REPEAT_1_168(m, d) BOOST_PP_REPEAT_1_167(m, d) m(2, 167, d)
223
# define BOOST_PP_REPEAT_1_169(m, d) BOOST_PP_REPEAT_1_168(m, d) m(2, 168, d)
224
# define BOOST_PP_REPEAT_1_170(m, d) BOOST_PP_REPEAT_1_169(m, d) m(2, 169, d)
225
# define BOOST_PP_REPEAT_1_171(m, d) BOOST_PP_REPEAT_1_170(m, d) m(2, 170, d)
226
# define BOOST_PP_REPEAT_1_172(m, d) BOOST_PP_REPEAT_1_171(m, d) m(2, 171, d)
227
# define BOOST_PP_REPEAT_1_173(m, d) BOOST_PP_REPEAT_1_172(m, d) m(2, 172, d)
228
# define BOOST_PP_REPEAT_1_174(m, d) BOOST_PP_REPEAT_1_173(m, d) m(2, 173, d)
229
# define BOOST_PP_REPEAT_1_175(m, d) BOOST_PP_REPEAT_1_174(m, d) m(2, 174, d)
230
# define BOOST_PP_REPEAT_1_176(m, d) BOOST_PP_REPEAT_1_175(m, d) m(2, 175, d)
231
# define BOOST_PP_REPEAT_1_177(m, d) BOOST_PP_REPEAT_1_176(m, d) m(2, 176, d)
232
# define BOOST_PP_REPEAT_1_178(m, d) BOOST_PP_REPEAT_1_177(m, d) m(2, 177, d)
233
# define BOOST_PP_REPEAT_1_179(m, d) BOOST_PP_REPEAT_1_178(m, d) m(2, 178, d)
234
# define BOOST_PP_REPEAT_1_180(m, d) BOOST_PP_REPEAT_1_179(m, d) m(2, 179, d)
235
# define BOOST_PP_REPEAT_1_181(m, d) BOOST_PP_REPEAT_1_180(m, d) m(2, 180, d)
236
# define BOOST_PP_REPEAT_1_182(m, d) BOOST_PP_REPEAT_1_181(m, d) m(2, 181, d)
237
# define BOOST_PP_REPEAT_1_183(m, d) BOOST_PP_REPEAT_1_182(m, d) m(2, 182, d)
238
# define BOOST_PP_REPEAT_1_184(m, d) BOOST_PP_REPEAT_1_183(m, d) m(2, 183, d)
239
# define BOOST_PP_REPEAT_1_185(m, d) BOOST_PP_REPEAT_1_184(m, d) m(2, 184, d)
240
# define BOOST_PP_REPEAT_1_186(m, d) BOOST_PP_REPEAT_1_185(m, d) m(2, 185, d)
241
# define BOOST_PP_REPEAT_1_187(m, d) BOOST_PP_REPEAT_1_186(m, d) m(2, 186, d)
242
# define BOOST_PP_REPEAT_1_188(m, d) BOOST_PP_REPEAT_1_187(m, d) m(2, 187, d)
243
# define BOOST_PP_REPEAT_1_189(m, d) BOOST_PP_REPEAT_1_188(m, d) m(2, 188, d)
244
# define BOOST_PP_REPEAT_1_190(m, d) BOOST_PP_REPEAT_1_189(m, d) m(2, 189, d)
245
# define BOOST_PP_REPEAT_1_191(m, d) BOOST_PP_REPEAT_1_190(m, d) m(2, 190, d)
246
# define BOOST_PP_REPEAT_1_192(m, d) BOOST_PP_REPEAT_1_191(m, d) m(2, 191, d)
247
# define BOOST_PP_REPEAT_1_193(m, d) BOOST_PP_REPEAT_1_192(m, d) m(2, 192, d)
248
# define BOOST_PP_REPEAT_1_194(m, d) BOOST_PP_REPEAT_1_193(m, d) m(2, 193, d)
249
# define BOOST_PP_REPEAT_1_195(m, d) BOOST_PP_REPEAT_1_194(m, d) m(2, 194, d)
250
# define BOOST_PP_REPEAT_1_196(m, d) BOOST_PP_REPEAT_1_195(m, d) m(2, 195, d)
251
# define BOOST_PP_REPEAT_1_197(m, d) BOOST_PP_REPEAT_1_196(m, d) m(2, 196, d)
252
# define BOOST_PP_REPEAT_1_198(m, d) BOOST_PP_REPEAT_1_197(m, d) m(2, 197, d)
253
# define BOOST_PP_REPEAT_1_199(m, d) BOOST_PP_REPEAT_1_198(m, d) m(2, 198, d)
254
# define BOOST_PP_REPEAT_1_200(m, d) BOOST_PP_REPEAT_1_199(m, d) m(2, 199, d)
255
# define BOOST_PP_REPEAT_1_201(m, d) BOOST_PP_REPEAT_1_200(m, d) m(2, 200, d)
256
# define BOOST_PP_REPEAT_1_202(m, d) BOOST_PP_REPEAT_1_201(m, d) m(2, 201, d)
257
# define BOOST_PP_REPEAT_1_203(m, d) BOOST_PP_REPEAT_1_202(m, d) m(2, 202, d)
258
# define BOOST_PP_REPEAT_1_204(m, d) BOOST_PP_REPEAT_1_203(m, d) m(2, 203, d)
259
# define BOOST_PP_REPEAT_1_205(m, d) BOOST_PP_REPEAT_1_204(m, d) m(2, 204, d)
260
# define BOOST_PP_REPEAT_1_206(m, d) BOOST_PP_REPEAT_1_205(m, d) m(2, 205, d)
261
# define BOOST_PP_REPEAT_1_207(m, d) BOOST_PP_REPEAT_1_206(m, d) m(2, 206, d)
262
# define BOOST_PP_REPEAT_1_208(m, d) BOOST_PP_REPEAT_1_207(m, d) m(2, 207, d)
263
# define BOOST_PP_REPEAT_1_209(m, d) BOOST_PP_REPEAT_1_208(m, d) m(2, 208, d)
264
# define BOOST_PP_REPEAT_1_210(m, d) BOOST_PP_REPEAT_1_209(m, d) m(2, 209, d)
265
# define BOOST_PP_REPEAT_1_211(m, d) BOOST_PP_REPEAT_1_210(m, d) m(2, 210, d)
266
# define BOOST_PP_REPEAT_1_212(m, d) BOOST_PP_REPEAT_1_211(m, d) m(2, 211, d)
267
# define BOOST_PP_REPEAT_1_213(m, d) BOOST_PP_REPEAT_1_212(m, d) m(2, 212, d)
268
# define BOOST_PP_REPEAT_1_214(m, d) BOOST_PP_REPEAT_1_213(m, d) m(2, 213, d)
269
# define BOOST_PP_REPEAT_1_215(m, d) BOOST_PP_REPEAT_1_214(m, d) m(2, 214, d)
270
# define BOOST_PP_REPEAT_1_216(m, d) BOOST_PP_REPEAT_1_215(m, d) m(2, 215, d)
271
# define BOOST_PP_REPEAT_1_217(m, d) BOOST_PP_REPEAT_1_216(m, d) m(2, 216, d)
272
# define BOOST_PP_REPEAT_1_218(m, d) BOOST_PP_REPEAT_1_217(m, d) m(2, 217, d)
273
# define BOOST_PP_REPEAT_1_219(m, d) BOOST_PP_REPEAT_1_218(m, d) m(2, 218, d)
274
# define BOOST_PP_REPEAT_1_220(m, d) BOOST_PP_REPEAT_1_219(m, d) m(2, 219, d)
275
# define BOOST_PP_REPEAT_1_221(m, d) BOOST_PP_REPEAT_1_220(m, d) m(2, 220, d)
276
# define BOOST_PP_REPEAT_1_222(m, d) BOOST_PP_REPEAT_1_221(m, d) m(2, 221, d)
277
# define BOOST_PP_REPEAT_1_223(m, d) BOOST_PP_REPEAT_1_222(m, d) m(2, 222, d)
278
# define BOOST_PP_REPEAT_1_224(m, d) BOOST_PP_REPEAT_1_223(m, d) m(2, 223, d)
279
# define BOOST_PP_REPEAT_1_225(m, d) BOOST_PP_REPEAT_1_224(m, d) m(2, 224, d)
280
# define BOOST_PP_REPEAT_1_226(m, d) BOOST_PP_REPEAT_1_225(m, d) m(2, 225, d)
281
# define BOOST_PP_REPEAT_1_227(m, d) BOOST_PP_REPEAT_1_226(m, d) m(2, 226, d)
282
# define BOOST_PP_REPEAT_1_228(m, d) BOOST_PP_REPEAT_1_227(m, d) m(2, 227, d)
283
# define BOOST_PP_REPEAT_1_229(m, d) BOOST_PP_REPEAT_1_228(m, d) m(2, 228, d)
284
# define BOOST_PP_REPEAT_1_230(m, d) BOOST_PP_REPEAT_1_229(m, d) m(2, 229, d)
285
# define BOOST_PP_REPEAT_1_231(m, d) BOOST_PP_REPEAT_1_230(m, d) m(2, 230, d)
286
# define BOOST_PP_REPEAT_1_232(m, d) BOOST_PP_REPEAT_1_231(m, d) m(2, 231, d)
287
# define BOOST_PP_REPEAT_1_233(m, d) BOOST_PP_REPEAT_1_232(m, d) m(2, 232, d)
288
# define BOOST_PP_REPEAT_1_234(m, d) BOOST_PP_REPEAT_1_233(m, d) m(2, 233, d)
289
# define BOOST_PP_REPEAT_1_235(m, d) BOOST_PP_REPEAT_1_234(m, d) m(2, 234, d)
290
# define BOOST_PP_REPEAT_1_236(m, d) BOOST_PP_REPEAT_1_235(m, d) m(2, 235, d)
291
# define BOOST_PP_REPEAT_1_237(m, d) BOOST_PP_REPEAT_1_236(m, d) m(2, 236, d)
292
# define BOOST_PP_REPEAT_1_238(m, d) BOOST_PP_REPEAT_1_237(m, d) m(2, 237, d)
293
# define BOOST_PP_REPEAT_1_239(m, d) BOOST_PP_REPEAT_1_238(m, d) m(2, 238, d)
294
# define BOOST_PP_REPEAT_1_240(m, d) BOOST_PP_REPEAT_1_239(m, d) m(2, 239, d)
295
# define BOOST_PP_REPEAT_1_241(m, d) BOOST_PP_REPEAT_1_240(m, d) m(2, 240, d)
296
# define BOOST_PP_REPEAT_1_242(m, d) BOOST_PP_REPEAT_1_241(m, d) m(2, 241, d)
297
# define BOOST_PP_REPEAT_1_243(m, d) BOOST_PP_REPEAT_1_242(m, d) m(2, 242, d)
298
# define BOOST_PP_REPEAT_1_244(m, d) BOOST_PP_REPEAT_1_243(m, d) m(2, 243, d)
299
# define BOOST_PP_REPEAT_1_245(m, d) BOOST_PP_REPEAT_1_244(m, d) m(2, 244, d)
300
# define BOOST_PP_REPEAT_1_246(m, d) BOOST_PP_REPEAT_1_245(m, d) m(2, 245, d)
301
# define BOOST_PP_REPEAT_1_247(m, d) BOOST_PP_REPEAT_1_246(m, d) m(2, 246, d)
302
# define BOOST_PP_REPEAT_1_248(m, d) BOOST_PP_REPEAT_1_247(m, d) m(2, 247, d)
303
# define BOOST_PP_REPEAT_1_249(m, d) BOOST_PP_REPEAT_1_248(m, d) m(2, 248, d)
304
# define BOOST_PP_REPEAT_1_250(m, d) BOOST_PP_REPEAT_1_249(m, d) m(2, 249, d)
305
# define BOOST_PP_REPEAT_1_251(m, d) BOOST_PP_REPEAT_1_250(m, d) m(2, 250, d)
306
# define BOOST_PP_REPEAT_1_252(m, d) BOOST_PP_REPEAT_1_251(m, d) m(2, 251, d)
307
# define BOOST_PP_REPEAT_1_253(m, d) BOOST_PP_REPEAT_1_252(m, d) m(2, 252, d)
308
# define BOOST_PP_REPEAT_1_254(m, d) BOOST_PP_REPEAT_1_253(m, d) m(2, 253, d)
309
# define BOOST_PP_REPEAT_1_255(m, d) BOOST_PP_REPEAT_1_254(m, d) m(2, 254, d)
310
# define BOOST_PP_REPEAT_1_256(m, d) BOOST_PP_REPEAT_1_255(m, d) m(2, 255, d)
311
#
312
# define BOOST_PP_REPEAT_2_0(m, d)
313
# define BOOST_PP_REPEAT_2_1(m, d) m(3, 0, d)
314
# define BOOST_PP_REPEAT_2_2(m, d) BOOST_PP_REPEAT_2_1(m, d) m(3, 1, d)
315
# define BOOST_PP_REPEAT_2_3(m, d) BOOST_PP_REPEAT_2_2(m, d) m(3, 2, d)
316
# define BOOST_PP_REPEAT_2_4(m, d) BOOST_PP_REPEAT_2_3(m, d) m(3, 3, d)
317
# define BOOST_PP_REPEAT_2_5(m, d) BOOST_PP_REPEAT_2_4(m, d) m(3, 4, d)
318
# define BOOST_PP_REPEAT_2_6(m, d) BOOST_PP_REPEAT_2_5(m, d) m(3, 5, d)
319
# define BOOST_PP_REPEAT_2_7(m, d) BOOST_PP_REPEAT_2_6(m, d) m(3, 6, d)
320
# define BOOST_PP_REPEAT_2_8(m, d) BOOST_PP_REPEAT_2_7(m, d) m(3, 7, d)
321
# define BOOST_PP_REPEAT_2_9(m, d) BOOST_PP_REPEAT_2_8(m, d) m(3, 8, d)
322
# define BOOST_PP_REPEAT_2_10(m, d) BOOST_PP_REPEAT_2_9(m, d) m(3, 9, d)
323
# define BOOST_PP_REPEAT_2_11(m, d) BOOST_PP_REPEAT_2_10(m, d) m(3, 10, d)
324
# define BOOST_PP_REPEAT_2_12(m, d) BOOST_PP_REPEAT_2_11(m, d) m(3, 11, d)
325
# define BOOST_PP_REPEAT_2_13(m, d) BOOST_PP_REPEAT_2_12(m, d) m(3, 12, d)
326
# define BOOST_PP_REPEAT_2_14(m, d) BOOST_PP_REPEAT_2_13(m, d) m(3, 13, d)
327
# define BOOST_PP_REPEAT_2_15(m, d) BOOST_PP_REPEAT_2_14(m, d) m(3, 14, d)
328
# define BOOST_PP_REPEAT_2_16(m, d) BOOST_PP_REPEAT_2_15(m, d) m(3, 15, d)
329
# define BOOST_PP_REPEAT_2_17(m, d) BOOST_PP_REPEAT_2_16(m, d) m(3, 16, d)
330
# define BOOST_PP_REPEAT_2_18(m, d) BOOST_PP_REPEAT_2_17(m, d) m(3, 17, d)
331
# define BOOST_PP_REPEAT_2_19(m, d) BOOST_PP_REPEAT_2_18(m, d) m(3, 18, d)
332
# define BOOST_PP_REPEAT_2_20(m, d) BOOST_PP_REPEAT_2_19(m, d) m(3, 19, d)
333
# define BOOST_PP_REPEAT_2_21(m, d) BOOST_PP_REPEAT_2_20(m, d) m(3, 20, d)
334
# define BOOST_PP_REPEAT_2_22(m, d) BOOST_PP_REPEAT_2_21(m, d) m(3, 21, d)
335
# define BOOST_PP_REPEAT_2_23(m, d) BOOST_PP_REPEAT_2_22(m, d) m(3, 22, d)
336
# define BOOST_PP_REPEAT_2_24(m, d) BOOST_PP_REPEAT_2_23(m, d) m(3, 23, d)
337
# define BOOST_PP_REPEAT_2_25(m, d) BOOST_PP_REPEAT_2_24(m, d) m(3, 24, d)
338
# define BOOST_PP_REPEAT_2_26(m, d) BOOST_PP_REPEAT_2_25(m, d) m(3, 25, d)
339
# define BOOST_PP_REPEAT_2_27(m, d) BOOST_PP_REPEAT_2_26(m, d) m(3, 26, d)
340
# define BOOST_PP_REPEAT_2_28(m, d) BOOST_PP_REPEAT_2_27(m, d) m(3, 27, d)
341
# define BOOST_PP_REPEAT_2_29(m, d) BOOST_PP_REPEAT_2_28(m, d) m(3, 28, d)
342
# define BOOST_PP_REPEAT_2_30(m, d) BOOST_PP_REPEAT_2_29(m, d) m(3, 29, d)
343
# define BOOST_PP_REPEAT_2_31(m, d) BOOST_PP_REPEAT_2_30(m, d) m(3, 30, d)
344
# define BOOST_PP_REPEAT_2_32(m, d) BOOST_PP_REPEAT_2_31(m, d) m(3, 31, d)
345
# define BOOST_PP_REPEAT_2_33(m, d) BOOST_PP_REPEAT_2_32(m, d) m(3, 32, d)
346
# define BOOST_PP_REPEAT_2_34(m, d) BOOST_PP_REPEAT_2_33(m, d) m(3, 33, d)
347
# define BOOST_PP_REPEAT_2_35(m, d) BOOST_PP_REPEAT_2_34(m, d) m(3, 34, d)
348
# define BOOST_PP_REPEAT_2_36(m, d) BOOST_PP_REPEAT_2_35(m, d) m(3, 35, d)
349
# define BOOST_PP_REPEAT_2_37(m, d) BOOST_PP_REPEAT_2_36(m, d) m(3, 36, d)
350
# define BOOST_PP_REPEAT_2_38(m, d) BOOST_PP_REPEAT_2_37(m, d) m(3, 37, d)
351
# define BOOST_PP_REPEAT_2_39(m, d) BOOST_PP_REPEAT_2_38(m, d) m(3, 38, d)
352
# define BOOST_PP_REPEAT_2_40(m, d) BOOST_PP_REPEAT_2_39(m, d) m(3, 39, d)
353
# define BOOST_PP_REPEAT_2_41(m, d) BOOST_PP_REPEAT_2_40(m, d) m(3, 40, d)
354
# define BOOST_PP_REPEAT_2_42(m, d) BOOST_PP_REPEAT_2_41(m, d) m(3, 41, d)
355
# define BOOST_PP_REPEAT_2_43(m, d) BOOST_PP_REPEAT_2_42(m, d) m(3, 42, d)
356
# define BOOST_PP_REPEAT_2_44(m, d) BOOST_PP_REPEAT_2_43(m, d) m(3, 43, d)
357
# define BOOST_PP_REPEAT_2_45(m, d) BOOST_PP_REPEAT_2_44(m, d) m(3, 44, d)
358
# define BOOST_PP_REPEAT_2_46(m, d) BOOST_PP_REPEAT_2_45(m, d) m(3, 45, d)
359
# define BOOST_PP_REPEAT_2_47(m, d) BOOST_PP_REPEAT_2_46(m, d) m(3, 46, d)
360
# define BOOST_PP_REPEAT_2_48(m, d) BOOST_PP_REPEAT_2_47(m, d) m(3, 47, d)
361
# define BOOST_PP_REPEAT_2_49(m, d) BOOST_PP_REPEAT_2_48(m, d) m(3, 48, d)
362
# define BOOST_PP_REPEAT_2_50(m, d) BOOST_PP_REPEAT_2_49(m, d) m(3, 49, d)
363
# define BOOST_PP_REPEAT_2_51(m, d) BOOST_PP_REPEAT_2_50(m, d) m(3, 50, d)
364
# define BOOST_PP_REPEAT_2_52(m, d) BOOST_PP_REPEAT_2_51(m, d) m(3, 51, d)
365
# define BOOST_PP_REPEAT_2_53(m, d) BOOST_PP_REPEAT_2_52(m, d) m(3, 52, d)
366
# define BOOST_PP_REPEAT_2_54(m, d) BOOST_PP_REPEAT_2_53(m, d) m(3, 53, d)
367
# define BOOST_PP_REPEAT_2_55(m, d) BOOST_PP_REPEAT_2_54(m, d) m(3, 54, d)
368
# define BOOST_PP_REPEAT_2_56(m, d) BOOST_PP_REPEAT_2_55(m, d) m(3, 55, d)
369
# define BOOST_PP_REPEAT_2_57(m, d) BOOST_PP_REPEAT_2_56(m, d) m(3, 56, d)
370
# define BOOST_PP_REPEAT_2_58(m, d) BOOST_PP_REPEAT_2_57(m, d) m(3, 57, d)
371
# define BOOST_PP_REPEAT_2_59(m, d) BOOST_PP_REPEAT_2_58(m, d) m(3, 58, d)
372
# define BOOST_PP_REPEAT_2_60(m, d) BOOST_PP_REPEAT_2_59(m, d) m(3, 59, d)
373
# define BOOST_PP_REPEAT_2_61(m, d) BOOST_PP_REPEAT_2_60(m, d) m(3, 60, d)
374
# define BOOST_PP_REPEAT_2_62(m, d) BOOST_PP_REPEAT_2_61(m, d) m(3, 61, d)
375
# define BOOST_PP_REPEAT_2_63(m, d) BOOST_PP_REPEAT_2_62(m, d) m(3, 62, d)
376
# define BOOST_PP_REPEAT_2_64(m, d) BOOST_PP_REPEAT_2_63(m, d) m(3, 63, d)
377
# define BOOST_PP_REPEAT_2_65(m, d) BOOST_PP_REPEAT_2_64(m, d) m(3, 64, d)
378
# define BOOST_PP_REPEAT_2_66(m, d) BOOST_PP_REPEAT_2_65(m, d) m(3, 65, d)
379
# define BOOST_PP_REPEAT_2_67(m, d) BOOST_PP_REPEAT_2_66(m, d) m(3, 66, d)
380
# define BOOST_PP_REPEAT_2_68(m, d) BOOST_PP_REPEAT_2_67(m, d) m(3, 67, d)
381
# define BOOST_PP_REPEAT_2_69(m, d) BOOST_PP_REPEAT_2_68(m, d) m(3, 68, d)
382
# define BOOST_PP_REPEAT_2_70(m, d) BOOST_PP_REPEAT_2_69(m, d) m(3, 69, d)
383
# define BOOST_PP_REPEAT_2_71(m, d) BOOST_PP_REPEAT_2_70(m, d) m(3, 70, d)
384
# define BOOST_PP_REPEAT_2_72(m, d) BOOST_PP_REPEAT_2_71(m, d) m(3, 71, d)
385
# define BOOST_PP_REPEAT_2_73(m, d) BOOST_PP_REPEAT_2_72(m, d) m(3, 72, d)
386
# define BOOST_PP_REPEAT_2_74(m, d) BOOST_PP_REPEAT_2_73(m, d) m(3, 73, d)
387
# define BOOST_PP_REPEAT_2_75(m, d) BOOST_PP_REPEAT_2_74(m, d) m(3, 74, d)
388
# define BOOST_PP_REPEAT_2_76(m, d) BOOST_PP_REPEAT_2_75(m, d) m(3, 75, d)
389
# define BOOST_PP_REPEAT_2_77(m, d) BOOST_PP_REPEAT_2_76(m, d) m(3, 76, d)
390
# define BOOST_PP_REPEAT_2_78(m, d) BOOST_PP_REPEAT_2_77(m, d) m(3, 77, d)
391
# define BOOST_PP_REPEAT_2_79(m, d) BOOST_PP_REPEAT_2_78(m, d) m(3, 78, d)
392
# define BOOST_PP_REPEAT_2_80(m, d) BOOST_PP_REPEAT_2_79(m, d) m(3, 79, d)
393
# define BOOST_PP_REPEAT_2_81(m, d) BOOST_PP_REPEAT_2_80(m, d) m(3, 80, d)
394
# define BOOST_PP_REPEAT_2_82(m, d) BOOST_PP_REPEAT_2_81(m, d) m(3, 81, d)
395
# define BOOST_PP_REPEAT_2_83(m, d) BOOST_PP_REPEAT_2_82(m, d) m(3, 82, d)
396
# define BOOST_PP_REPEAT_2_84(m, d) BOOST_PP_REPEAT_2_83(m, d) m(3, 83, d)
397
# define BOOST_PP_REPEAT_2_85(m, d) BOOST_PP_REPEAT_2_84(m, d) m(3, 84, d)
398
# define BOOST_PP_REPEAT_2_86(m, d) BOOST_PP_REPEAT_2_85(m, d) m(3, 85, d)
399
# define BOOST_PP_REPEAT_2_87(m, d) BOOST_PP_REPEAT_2_86(m, d) m(3, 86, d)
400
# define BOOST_PP_REPEAT_2_88(m, d) BOOST_PP_REPEAT_2_87(m, d) m(3, 87, d)
401
# define BOOST_PP_REPEAT_2_89(m, d) BOOST_PP_REPEAT_2_88(m, d) m(3, 88, d)
402
# define BOOST_PP_REPEAT_2_90(m, d) BOOST_PP_REPEAT_2_89(m, d) m(3, 89, d)
403
# define BOOST_PP_REPEAT_2_91(m, d) BOOST_PP_REPEAT_2_90(m, d) m(3, 90, d)
404
# define BOOST_PP_REPEAT_2_92(m, d) BOOST_PP_REPEAT_2_91(m, d) m(3, 91, d)
405
# define BOOST_PP_REPEAT_2_93(m, d) BOOST_PP_REPEAT_2_92(m, d) m(3, 92, d)
406
# define BOOST_PP_REPEAT_2_94(m, d) BOOST_PP_REPEAT_2_93(m, d) m(3, 93, d)
407
# define BOOST_PP_REPEAT_2_95(m, d) BOOST_PP_REPEAT_2_94(m, d) m(3, 94, d)
408
# define BOOST_PP_REPEAT_2_96(m, d) BOOST_PP_REPEAT_2_95(m, d) m(3, 95, d)
409
# define BOOST_PP_REPEAT_2_97(m, d) BOOST_PP_REPEAT_2_96(m, d) m(3, 96, d)
410
# define BOOST_PP_REPEAT_2_98(m, d) BOOST_PP_REPEAT_2_97(m, d) m(3, 97, d)
411
# define BOOST_PP_REPEAT_2_99(m, d) BOOST_PP_REPEAT_2_98(m, d) m(3, 98, d)
412
# define BOOST_PP_REPEAT_2_100(m, d) BOOST_PP_REPEAT_2_99(m, d) m(3, 99, d)
413
# define BOOST_PP_REPEAT_2_101(m, d) BOOST_PP_REPEAT_2_100(m, d) m(3, 100, d)
414
# define BOOST_PP_REPEAT_2_102(m, d) BOOST_PP_REPEAT_2_101(m, d) m(3, 101, d)
415
# define BOOST_PP_REPEAT_2_103(m, d) BOOST_PP_REPEAT_2_102(m, d) m(3, 102, d)
416
# define BOOST_PP_REPEAT_2_104(m, d) BOOST_PP_REPEAT_2_103(m, d) m(3, 103, d)
417
# define BOOST_PP_REPEAT_2_105(m, d) BOOST_PP_REPEAT_2_104(m, d) m(3, 104, d)
418
# define BOOST_PP_REPEAT_2_106(m, d) BOOST_PP_REPEAT_2_105(m, d) m(3, 105, d)
419
# define BOOST_PP_REPEAT_2_107(m, d) BOOST_PP_REPEAT_2_106(m, d) m(3, 106, d)
420
# define BOOST_PP_REPEAT_2_108(m, d) BOOST_PP_REPEAT_2_107(m, d) m(3, 107, d)
421
# define BOOST_PP_REPEAT_2_109(m, d) BOOST_PP_REPEAT_2_108(m, d) m(3, 108, d)
422
# define BOOST_PP_REPEAT_2_110(m, d) BOOST_PP_REPEAT_2_109(m, d) m(3, 109, d)
423
# define BOOST_PP_REPEAT_2_111(m, d) BOOST_PP_REPEAT_2_110(m, d) m(3, 110, d)
424
# define BOOST_PP_REPEAT_2_112(m, d) BOOST_PP_REPEAT_2_111(m, d) m(3, 111, d)
425
# define BOOST_PP_REPEAT_2_113(m, d) BOOST_PP_REPEAT_2_112(m, d) m(3, 112, d)
426
# define BOOST_PP_REPEAT_2_114(m, d) BOOST_PP_REPEAT_2_113(m, d) m(3, 113, d)
427
# define BOOST_PP_REPEAT_2_115(m, d) BOOST_PP_REPEAT_2_114(m, d) m(3, 114, d)
428
# define BOOST_PP_REPEAT_2_116(m, d) BOOST_PP_REPEAT_2_115(m, d) m(3, 115, d)
429
# define BOOST_PP_REPEAT_2_117(m, d) BOOST_PP_REPEAT_2_116(m, d) m(3, 116, d)
430
# define BOOST_PP_REPEAT_2_118(m, d) BOOST_PP_REPEAT_2_117(m, d) m(3, 117, d)
431
# define BOOST_PP_REPEAT_2_119(m, d) BOOST_PP_REPEAT_2_118(m, d) m(3, 118, d)
432
# define BOOST_PP_REPEAT_2_120(m, d) BOOST_PP_REPEAT_2_119(m, d) m(3, 119, d)
433
# define BOOST_PP_REPEAT_2_121(m, d) BOOST_PP_REPEAT_2_120(m, d) m(3, 120, d)
434
# define BOOST_PP_REPEAT_2_122(m, d) BOOST_PP_REPEAT_2_121(m, d) m(3, 121, d)
435
# define BOOST_PP_REPEAT_2_123(m, d) BOOST_PP_REPEAT_2_122(m, d) m(3, 122, d)
436
# define BOOST_PP_REPEAT_2_124(m, d) BOOST_PP_REPEAT_2_123(m, d) m(3, 123, d)
437
# define BOOST_PP_REPEAT_2_125(m, d) BOOST_PP_REPEAT_2_124(m, d) m(3, 124, d)
438
# define BOOST_PP_REPEAT_2_126(m, d) BOOST_PP_REPEAT_2_125(m, d) m(3, 125, d)
439
# define BOOST_PP_REPEAT_2_127(m, d) BOOST_PP_REPEAT_2_126(m, d) m(3, 126, d)
440
# define BOOST_PP_REPEAT_2_128(m, d) BOOST_PP_REPEAT_2_127(m, d) m(3, 127, d)
441
# define BOOST_PP_REPEAT_2_129(m, d) BOOST_PP_REPEAT_2_128(m, d) m(3, 128, d)
442
# define BOOST_PP_REPEAT_2_130(m, d) BOOST_PP_REPEAT_2_129(m, d) m(3, 129, d)
443
# define BOOST_PP_REPEAT_2_131(m, d) BOOST_PP_REPEAT_2_130(m, d) m(3, 130, d)
444
# define BOOST_PP_REPEAT_2_132(m, d) BOOST_PP_REPEAT_2_131(m, d) m(3, 131, d)
445
# define BOOST_PP_REPEAT_2_133(m, d) BOOST_PP_REPEAT_2_132(m, d) m(3, 132, d)
446
# define BOOST_PP_REPEAT_2_134(m, d) BOOST_PP_REPEAT_2_133(m, d) m(3, 133, d)
447
# define BOOST_PP_REPEAT_2_135(m, d) BOOST_PP_REPEAT_2_134(m, d) m(3, 134, d)
448
# define BOOST_PP_REPEAT_2_136(m, d) BOOST_PP_REPEAT_2_135(m, d) m(3, 135, d)
449
# define BOOST_PP_REPEAT_2_137(m, d) BOOST_PP_REPEAT_2_136(m, d) m(3, 136, d)
450
# define BOOST_PP_REPEAT_2_138(m, d) BOOST_PP_REPEAT_2_137(m, d) m(3, 137, d)
451
# define BOOST_PP_REPEAT_2_139(m, d) BOOST_PP_REPEAT_2_138(m, d) m(3, 138, d)
452
# define BOOST_PP_REPEAT_2_140(m, d) BOOST_PP_REPEAT_2_139(m, d) m(3, 139, d)
453
# define BOOST_PP_REPEAT_2_141(m, d) BOOST_PP_REPEAT_2_140(m, d) m(3, 140, d)
454
# define BOOST_PP_REPEAT_2_142(m, d) BOOST_PP_REPEAT_2_141(m, d) m(3, 141, d)
455
# define BOOST_PP_REPEAT_2_143(m, d) BOOST_PP_REPEAT_2_142(m, d) m(3, 142, d)
456
# define BOOST_PP_REPEAT_2_144(m, d) BOOST_PP_REPEAT_2_143(m, d) m(3, 143, d)
457
# define BOOST_PP_REPEAT_2_145(m, d) BOOST_PP_REPEAT_2_144(m, d) m(3, 144, d)
458
# define BOOST_PP_REPEAT_2_146(m, d) BOOST_PP_REPEAT_2_145(m, d) m(3, 145, d)
459
# define BOOST_PP_REPEAT_2_147(m, d) BOOST_PP_REPEAT_2_146(m, d) m(3, 146, d)
460
# define BOOST_PP_REPEAT_2_148(m, d) BOOST_PP_REPEAT_2_147(m, d) m(3, 147, d)
461
# define BOOST_PP_REPEAT_2_149(m, d) BOOST_PP_REPEAT_2_148(m, d) m(3, 148, d)
462
# define BOOST_PP_REPEAT_2_150(m, d) BOOST_PP_REPEAT_2_149(m, d) m(3, 149, d)
463
# define BOOST_PP_REPEAT_2_151(m, d) BOOST_PP_REPEAT_2_150(m, d) m(3, 150, d)
464
# define BOOST_PP_REPEAT_2_152(m, d) BOOST_PP_REPEAT_2_151(m, d) m(3, 151, d)
465
# define BOOST_PP_REPEAT_2_153(m, d) BOOST_PP_REPEAT_2_152(m, d) m(3, 152, d)
466
# define BOOST_PP_REPEAT_2_154(m, d) BOOST_PP_REPEAT_2_153(m, d) m(3, 153, d)
467
# define BOOST_PP_REPEAT_2_155(m, d) BOOST_PP_REPEAT_2_154(m, d) m(3, 154, d)
468
# define BOOST_PP_REPEAT_2_156(m, d) BOOST_PP_REPEAT_2_155(m, d) m(3, 155, d)
469
# define BOOST_PP_REPEAT_2_157(m, d) BOOST_PP_REPEAT_2_156(m, d) m(3, 156, d)
470
# define BOOST_PP_REPEAT_2_158(m, d) BOOST_PP_REPEAT_2_157(m, d) m(3, 157, d)
471
# define BOOST_PP_REPEAT_2_159(m, d) BOOST_PP_REPEAT_2_158(m, d) m(3, 158, d)
472
# define BOOST_PP_REPEAT_2_160(m, d) BOOST_PP_REPEAT_2_159(m, d) m(3, 159, d)
473
# define BOOST_PP_REPEAT_2_161(m, d) BOOST_PP_REPEAT_2_160(m, d) m(3, 160, d)
474
# define BOOST_PP_REPEAT_2_162(m, d) BOOST_PP_REPEAT_2_161(m, d) m(3, 161, d)
475
# define BOOST_PP_REPEAT_2_163(m, d) BOOST_PP_REPEAT_2_162(m, d) m(3, 162, d)
476
# define BOOST_PP_REPEAT_2_164(m, d) BOOST_PP_REPEAT_2_163(m, d) m(3, 163, d)
477
# define BOOST_PP_REPEAT_2_165(m, d) BOOST_PP_REPEAT_2_164(m, d) m(3, 164, d)
478
# define BOOST_PP_REPEAT_2_166(m, d) BOOST_PP_REPEAT_2_165(m, d) m(3, 165, d)
479
# define BOOST_PP_REPEAT_2_167(m, d) BOOST_PP_REPEAT_2_166(m, d) m(3, 166, d)
480
# define BOOST_PP_REPEAT_2_168(m, d) BOOST_PP_REPEAT_2_167(m, d) m(3, 167, d)
481
# define BOOST_PP_REPEAT_2_169(m, d) BOOST_PP_REPEAT_2_168(m, d) m(3, 168, d)
482
# define BOOST_PP_REPEAT_2_170(m, d) BOOST_PP_REPEAT_2_169(m, d) m(3, 169, d)
483
# define BOOST_PP_REPEAT_2_171(m, d) BOOST_PP_REPEAT_2_170(m, d) m(3, 170, d)
484
# define BOOST_PP_REPEAT_2_172(m, d) BOOST_PP_REPEAT_2_171(m, d) m(3, 171, d)
485
# define BOOST_PP_REPEAT_2_173(m, d) BOOST_PP_REPEAT_2_172(m, d) m(3, 172, d)
486
# define BOOST_PP_REPEAT_2_174(m, d) BOOST_PP_REPEAT_2_173(m, d) m(3, 173, d)
487
# define BOOST_PP_REPEAT_2_175(m, d) BOOST_PP_REPEAT_2_174(m, d) m(3, 174, d)
488
# define BOOST_PP_REPEAT_2_176(m, d) BOOST_PP_REPEAT_2_175(m, d) m(3, 175, d)
489
# define BOOST_PP_REPEAT_2_177(m, d) BOOST_PP_REPEAT_2_176(m, d) m(3, 176, d)
490
# define BOOST_PP_REPEAT_2_178(m, d) BOOST_PP_REPEAT_2_177(m, d) m(3, 177, d)
491
# define BOOST_PP_REPEAT_2_179(m, d) BOOST_PP_REPEAT_2_178(m, d) m(3, 178, d)
492
# define BOOST_PP_REPEAT_2_180(m, d) BOOST_PP_REPEAT_2_179(m, d) m(3, 179, d)
493
# define BOOST_PP_REPEAT_2_181(m, d) BOOST_PP_REPEAT_2_180(m, d) m(3, 180, d)
494
# define BOOST_PP_REPEAT_2_182(m, d) BOOST_PP_REPEAT_2_181(m, d) m(3, 181, d)
495
# define BOOST_PP_REPEAT_2_183(m, d) BOOST_PP_REPEAT_2_182(m, d) m(3, 182, d)
496
# define BOOST_PP_REPEAT_2_184(m, d) BOOST_PP_REPEAT_2_183(m, d) m(3, 183, d)
497
# define BOOST_PP_REPEAT_2_185(m, d) BOOST_PP_REPEAT_2_184(m, d) m(3, 184, d)
498
# define BOOST_PP_REPEAT_2_186(m, d) BOOST_PP_REPEAT_2_185(m, d) m(3, 185, d)
499
# define BOOST_PP_REPEAT_2_187(m, d) BOOST_PP_REPEAT_2_186(m, d) m(3, 186, d)
500
# define BOOST_PP_REPEAT_2_188(m, d) BOOST_PP_REPEAT_2_187(m, d) m(3, 187, d)
501
# define BOOST_PP_REPEAT_2_189(m, d) BOOST_PP_REPEAT_2_188(m, d) m(3, 188, d)
502
# define BOOST_PP_REPEAT_2_190(m, d) BOOST_PP_REPEAT_2_189(m, d) m(3, 189, d)
503
# define BOOST_PP_REPEAT_2_191(m, d) BOOST_PP_REPEAT_2_190(m, d) m(3, 190, d)
504
# define BOOST_PP_REPEAT_2_192(m, d) BOOST_PP_REPEAT_2_191(m, d) m(3, 191, d)
505
# define BOOST_PP_REPEAT_2_193(m, d) BOOST_PP_REPEAT_2_192(m, d) m(3, 192, d)
506
# define BOOST_PP_REPEAT_2_194(m, d) BOOST_PP_REPEAT_2_193(m, d) m(3, 193, d)
507
# define BOOST_PP_REPEAT_2_195(m, d) BOOST_PP_REPEAT_2_194(m, d) m(3, 194, d)
508
# define BOOST_PP_REPEAT_2_196(m, d) BOOST_PP_REPEAT_2_195(m, d) m(3, 195, d)
509
# define BOOST_PP_REPEAT_2_197(m, d) BOOST_PP_REPEAT_2_196(m, d) m(3, 196, d)
510
# define BOOST_PP_REPEAT_2_198(m, d) BOOST_PP_REPEAT_2_197(m, d) m(3, 197, d)
511
# define BOOST_PP_REPEAT_2_199(m, d) BOOST_PP_REPEAT_2_198(m, d) m(3, 198, d)
512
# define BOOST_PP_REPEAT_2_200(m, d) BOOST_PP_REPEAT_2_199(m, d) m(3, 199, d)
513
# define BOOST_PP_REPEAT_2_201(m, d) BOOST_PP_REPEAT_2_200(m, d) m(3, 200, d)
514
# define BOOST_PP_REPEAT_2_202(m, d) BOOST_PP_REPEAT_2_201(m, d) m(3, 201, d)
515
# define BOOST_PP_REPEAT_2_203(m, d) BOOST_PP_REPEAT_2_202(m, d) m(3, 202, d)
516
# define BOOST_PP_REPEAT_2_204(m, d) BOOST_PP_REPEAT_2_203(m, d) m(3, 203, d)
517
# define BOOST_PP_REPEAT_2_205(m, d) BOOST_PP_REPEAT_2_204(m, d) m(3, 204, d)
518
# define BOOST_PP_REPEAT_2_206(m, d) BOOST_PP_REPEAT_2_205(m, d) m(3, 205, d)
519
# define BOOST_PP_REPEAT_2_207(m, d) BOOST_PP_REPEAT_2_206(m, d) m(3, 206, d)
520
# define BOOST_PP_REPEAT_2_208(m, d) BOOST_PP_REPEAT_2_207(m, d) m(3, 207, d)
521
# define BOOST_PP_REPEAT_2_209(m, d) BOOST_PP_REPEAT_2_208(m, d) m(3, 208, d)
522
# define BOOST_PP_REPEAT_2_210(m, d) BOOST_PP_REPEAT_2_209(m, d) m(3, 209, d)
523
# define BOOST_PP_REPEAT_2_211(m, d) BOOST_PP_REPEAT_2_210(m, d) m(3, 210, d)
524
# define BOOST_PP_REPEAT_2_212(m, d) BOOST_PP_REPEAT_2_211(m, d) m(3, 211, d)
525
# define BOOST_PP_REPEAT_2_213(m, d) BOOST_PP_REPEAT_2_212(m, d) m(3, 212, d)
526
# define BOOST_PP_REPEAT_2_214(m, d) BOOST_PP_REPEAT_2_213(m, d) m(3, 213, d)
527
# define BOOST_PP_REPEAT_2_215(m, d) BOOST_PP_REPEAT_2_214(m, d) m(3, 214, d)
528
# define BOOST_PP_REPEAT_2_216(m, d) BOOST_PP_REPEAT_2_215(m, d) m(3, 215, d)
529
# define BOOST_PP_REPEAT_2_217(m, d) BOOST_PP_REPEAT_2_216(m, d) m(3, 216, d)
530
# define BOOST_PP_REPEAT_2_218(m, d) BOOST_PP_REPEAT_2_217(m, d) m(3, 217, d)
531
# define BOOST_PP_REPEAT_2_219(m, d) BOOST_PP_REPEAT_2_218(m, d) m(3, 218, d)
532
# define BOOST_PP_REPEAT_2_220(m, d) BOOST_PP_REPEAT_2_219(m, d) m(3, 219, d)
533
# define BOOST_PP_REPEAT_2_221(m, d) BOOST_PP_REPEAT_2_220(m, d) m(3, 220, d)
534
# define BOOST_PP_REPEAT_2_222(m, d) BOOST_PP_REPEAT_2_221(m, d) m(3, 221, d)
535
# define BOOST_PP_REPEAT_2_223(m, d) BOOST_PP_REPEAT_2_222(m, d) m(3, 222, d)
536
# define BOOST_PP_REPEAT_2_224(m, d) BOOST_PP_REPEAT_2_223(m, d) m(3, 223, d)
537
# define BOOST_PP_REPEAT_2_225(m, d) BOOST_PP_REPEAT_2_224(m, d) m(3, 224, d)
538
# define BOOST_PP_REPEAT_2_226(m, d) BOOST_PP_REPEAT_2_225(m, d) m(3, 225, d)
539
# define BOOST_PP_REPEAT_2_227(m, d) BOOST_PP_REPEAT_2_226(m, d) m(3, 226, d)
540
# define BOOST_PP_REPEAT_2_228(m, d) BOOST_PP_REPEAT_2_227(m, d) m(3, 227, d)
541
# define BOOST_PP_REPEAT_2_229(m, d) BOOST_PP_REPEAT_2_228(m, d) m(3, 228, d)
542
# define BOOST_PP_REPEAT_2_230(m, d) BOOST_PP_REPEAT_2_229(m, d) m(3, 229, d)
543
# define BOOST_PP_REPEAT_2_231(m, d) BOOST_PP_REPEAT_2_230(m, d) m(3, 230, d)
544
# define BOOST_PP_REPEAT_2_232(m, d) BOOST_PP_REPEAT_2_231(m, d) m(3, 231, d)
545
# define BOOST_PP_REPEAT_2_233(m, d) BOOST_PP_REPEAT_2_232(m, d) m(3, 232, d)
546
# define BOOST_PP_REPEAT_2_234(m, d) BOOST_PP_REPEAT_2_233(m, d) m(3, 233, d)
547
# define BOOST_PP_REPEAT_2_235(m, d) BOOST_PP_REPEAT_2_234(m, d) m(3, 234, d)
548
# define BOOST_PP_REPEAT_2_236(m, d) BOOST_PP_REPEAT_2_235(m, d) m(3, 235, d)
549
# define BOOST_PP_REPEAT_2_237(m, d) BOOST_PP_REPEAT_2_236(m, d) m(3, 236, d)
550
# define BOOST_PP_REPEAT_2_238(m, d) BOOST_PP_REPEAT_2_237(m, d) m(3, 237, d)
551
# define BOOST_PP_REPEAT_2_239(m, d) BOOST_PP_REPEAT_2_238(m, d) m(3, 238, d)
552
# define BOOST_PP_REPEAT_2_240(m, d) BOOST_PP_REPEAT_2_239(m, d) m(3, 239, d)
553
# define BOOST_PP_REPEAT_2_241(m, d) BOOST_PP_REPEAT_2_240(m, d) m(3, 240, d)
554
# define BOOST_PP_REPEAT_2_242(m, d) BOOST_PP_REPEAT_2_241(m, d) m(3, 241, d)
555
# define BOOST_PP_REPEAT_2_243(m, d) BOOST_PP_REPEAT_2_242(m, d) m(3, 242, d)
556
# define BOOST_PP_REPEAT_2_244(m, d) BOOST_PP_REPEAT_2_243(m, d) m(3, 243, d)
557
# define BOOST_PP_REPEAT_2_245(m, d) BOOST_PP_REPEAT_2_244(m, d) m(3, 244, d)
558
# define BOOST_PP_REPEAT_2_246(m, d) BOOST_PP_REPEAT_2_245(m, d) m(3, 245, d)
559
# define BOOST_PP_REPEAT_2_247(m, d) BOOST_PP_REPEAT_2_246(m, d) m(3, 246, d)
560
# define BOOST_PP_REPEAT_2_248(m, d) BOOST_PP_REPEAT_2_247(m, d) m(3, 247, d)
561
# define BOOST_PP_REPEAT_2_249(m, d) BOOST_PP_REPEAT_2_248(m, d) m(3, 248, d)
562
# define BOOST_PP_REPEAT_2_250(m, d) BOOST_PP_REPEAT_2_249(m, d) m(3, 249, d)
563
# define BOOST_PP_REPEAT_2_251(m, d) BOOST_PP_REPEAT_2_250(m, d) m(3, 250, d)
564
# define BOOST_PP_REPEAT_2_252(m, d) BOOST_PP_REPEAT_2_251(m, d) m(3, 251, d)
565
# define BOOST_PP_REPEAT_2_253(m, d) BOOST_PP_REPEAT_2_252(m, d) m(3, 252, d)
566
# define BOOST_PP_REPEAT_2_254(m, d) BOOST_PP_REPEAT_2_253(m, d) m(3, 253, d)
567
# define BOOST_PP_REPEAT_2_255(m, d) BOOST_PP_REPEAT_2_254(m, d) m(3, 254, d)
568
# define BOOST_PP_REPEAT_2_256(m, d) BOOST_PP_REPEAT_2_255(m, d) m(3, 255, d)
569
#
570
# define BOOST_PP_REPEAT_3_0(m, d)
571
# define BOOST_PP_REPEAT_3_1(m, d) m(4, 0, d)
572
# define BOOST_PP_REPEAT_3_2(m, d) BOOST_PP_REPEAT_3_1(m, d) m(4, 1, d)
573
# define BOOST_PP_REPEAT_3_3(m, d) BOOST_PP_REPEAT_3_2(m, d) m(4, 2, d)
574
# define BOOST_PP_REPEAT_3_4(m, d) BOOST_PP_REPEAT_3_3(m, d) m(4, 3, d)
575
# define BOOST_PP_REPEAT_3_5(m, d) BOOST_PP_REPEAT_3_4(m, d) m(4, 4, d)
576
# define BOOST_PP_REPEAT_3_6(m, d) BOOST_PP_REPEAT_3_5(m, d) m(4, 5, d)
577
# define BOOST_PP_REPEAT_3_7(m, d) BOOST_PP_REPEAT_3_6(m, d) m(4, 6, d)
578
# define BOOST_PP_REPEAT_3_8(m, d) BOOST_PP_REPEAT_3_7(m, d) m(4, 7, d)
579
# define BOOST_PP_REPEAT_3_9(m, d) BOOST_PP_REPEAT_3_8(m, d) m(4, 8, d)
580
# define BOOST_PP_REPEAT_3_10(m, d) BOOST_PP_REPEAT_3_9(m, d) m(4, 9, d)
581
# define BOOST_PP_REPEAT_3_11(m, d) BOOST_PP_REPEAT_3_10(m, d) m(4, 10, d)
582
# define BOOST_PP_REPEAT_3_12(m, d) BOOST_PP_REPEAT_3_11(m, d) m(4, 11, d)
583
# define BOOST_PP_REPEAT_3_13(m, d) BOOST_PP_REPEAT_3_12(m, d) m(4, 12, d)
584
# define BOOST_PP_REPEAT_3_14(m, d) BOOST_PP_REPEAT_3_13(m, d) m(4, 13, d)
585
# define BOOST_PP_REPEAT_3_15(m, d) BOOST_PP_REPEAT_3_14(m, d) m(4, 14, d)
586
# define BOOST_PP_REPEAT_3_16(m, d) BOOST_PP_REPEAT_3_15(m, d) m(4, 15, d)
587
# define BOOST_PP_REPEAT_3_17(m, d) BOOST_PP_REPEAT_3_16(m, d) m(4, 16, d)
588
# define BOOST_PP_REPEAT_3_18(m, d) BOOST_PP_REPEAT_3_17(m, d) m(4, 17, d)
589
# define BOOST_PP_REPEAT_3_19(m, d) BOOST_PP_REPEAT_3_18(m, d) m(4, 18, d)
590
# define BOOST_PP_REPEAT_3_20(m, d) BOOST_PP_REPEAT_3_19(m, d) m(4, 19, d)
591
# define BOOST_PP_REPEAT_3_21(m, d) BOOST_PP_REPEAT_3_20(m, d) m(4, 20, d)
592
# define BOOST_PP_REPEAT_3_22(m, d) BOOST_PP_REPEAT_3_21(m, d) m(4, 21, d)
593
# define BOOST_PP_REPEAT_3_23(m, d) BOOST_PP_REPEAT_3_22(m, d) m(4, 22, d)
594
# define BOOST_PP_REPEAT_3_24(m, d) BOOST_PP_REPEAT_3_23(m, d) m(4, 23, d)
595
# define BOOST_PP_REPEAT_3_25(m, d) BOOST_PP_REPEAT_3_24(m, d) m(4, 24, d)
596
# define BOOST_PP_REPEAT_3_26(m, d) BOOST_PP_REPEAT_3_25(m, d) m(4, 25, d)
597
# define BOOST_PP_REPEAT_3_27(m, d) BOOST_PP_REPEAT_3_26(m, d) m(4, 26, d)
598
# define BOOST_PP_REPEAT_3_28(m, d) BOOST_PP_REPEAT_3_27(m, d) m(4, 27, d)
599
# define BOOST_PP_REPEAT_3_29(m, d) BOOST_PP_REPEAT_3_28(m, d) m(4, 28, d)
600
# define BOOST_PP_REPEAT_3_30(m, d) BOOST_PP_REPEAT_3_29(m, d) m(4, 29, d)
601
# define BOOST_PP_REPEAT_3_31(m, d) BOOST_PP_REPEAT_3_30(m, d) m(4, 30, d)
602
# define BOOST_PP_REPEAT_3_32(m, d) BOOST_PP_REPEAT_3_31(m, d) m(4, 31, d)
603
# define BOOST_PP_REPEAT_3_33(m, d) BOOST_PP_REPEAT_3_32(m, d) m(4, 32, d)
604
# define BOOST_PP_REPEAT_3_34(m, d) BOOST_PP_REPEAT_3_33(m, d) m(4, 33, d)
605
# define BOOST_PP_REPEAT_3_35(m, d) BOOST_PP_REPEAT_3_34(m, d) m(4, 34, d)
606
# define BOOST_PP_REPEAT_3_36(m, d) BOOST_PP_REPEAT_3_35(m, d) m(4, 35, d)
607
# define BOOST_PP_REPEAT_3_37(m, d) BOOST_PP_REPEAT_3_36(m, d) m(4, 36, d)
608
# define BOOST_PP_REPEAT_3_38(m, d) BOOST_PP_REPEAT_3_37(m, d) m(4, 37, d)
609
# define BOOST_PP_REPEAT_3_39(m, d) BOOST_PP_REPEAT_3_38(m, d) m(4, 38, d)
610
# define BOOST_PP_REPEAT_3_40(m, d) BOOST_PP_REPEAT_3_39(m, d) m(4, 39, d)
611
# define BOOST_PP_REPEAT_3_41(m, d) BOOST_PP_REPEAT_3_40(m, d) m(4, 40, d)
612
# define BOOST_PP_REPEAT_3_42(m, d) BOOST_PP_REPEAT_3_41(m, d) m(4, 41, d)
613
# define BOOST_PP_REPEAT_3_43(m, d) BOOST_PP_REPEAT_3_42(m, d) m(4, 42, d)
614
# define BOOST_PP_REPEAT_3_44(m, d) BOOST_PP_REPEAT_3_43(m, d) m(4, 43, d)
615
# define BOOST_PP_REPEAT_3_45(m, d) BOOST_PP_REPEAT_3_44(m, d) m(4, 44, d)
616
# define BOOST_PP_REPEAT_3_46(m, d) BOOST_PP_REPEAT_3_45(m, d) m(4, 45, d)
617
# define BOOST_PP_REPEAT_3_47(m, d) BOOST_PP_REPEAT_3_46(m, d) m(4, 46, d)
618
# define BOOST_PP_REPEAT_3_48(m, d) BOOST_PP_REPEAT_3_47(m, d) m(4, 47, d)
619
# define BOOST_PP_REPEAT_3_49(m, d) BOOST_PP_REPEAT_3_48(m, d) m(4, 48, d)
620
# define BOOST_PP_REPEAT_3_50(m, d) BOOST_PP_REPEAT_3_49(m, d) m(4, 49, d)
621
# define BOOST_PP_REPEAT_3_51(m, d) BOOST_PP_REPEAT_3_50(m, d) m(4, 50, d)
622
# define BOOST_PP_REPEAT_3_52(m, d) BOOST_PP_REPEAT_3_51(m, d) m(4, 51, d)
623
# define BOOST_PP_REPEAT_3_53(m, d) BOOST_PP_REPEAT_3_52(m, d) m(4, 52, d)
624
# define BOOST_PP_REPEAT_3_54(m, d) BOOST_PP_REPEAT_3_53(m, d) m(4, 53, d)
625
# define BOOST_PP_REPEAT_3_55(m, d) BOOST_PP_REPEAT_3_54(m, d) m(4, 54, d)
626
# define BOOST_PP_REPEAT_3_56(m, d) BOOST_PP_REPEAT_3_55(m, d) m(4, 55, d)
627
# define BOOST_PP_REPEAT_3_57(m, d) BOOST_PP_REPEAT_3_56(m, d) m(4, 56, d)
628
# define BOOST_PP_REPEAT_3_58(m, d) BOOST_PP_REPEAT_3_57(m, d) m(4, 57, d)
629
# define BOOST_PP_REPEAT_3_59(m, d) BOOST_PP_REPEAT_3_58(m, d) m(4, 58, d)
630
# define BOOST_PP_REPEAT_3_60(m, d) BOOST_PP_REPEAT_3_59(m, d) m(4, 59, d)
631
# define BOOST_PP_REPEAT_3_61(m, d) BOOST_PP_REPEAT_3_60(m, d) m(4, 60, d)
632
# define BOOST_PP_REPEAT_3_62(m, d) BOOST_PP_REPEAT_3_61(m, d) m(4, 61, d)
633
# define BOOST_PP_REPEAT_3_63(m, d) BOOST_PP_REPEAT_3_62(m, d) m(4, 62, d)
634
# define BOOST_PP_REPEAT_3_64(m, d) BOOST_PP_REPEAT_3_63(m, d) m(4, 63, d)
635
# define BOOST_PP_REPEAT_3_65(m, d) BOOST_PP_REPEAT_3_64(m, d) m(4, 64, d)
636
# define BOOST_PP_REPEAT_3_66(m, d) BOOST_PP_REPEAT_3_65(m, d) m(4, 65, d)
637
# define BOOST_PP_REPEAT_3_67(m, d) BOOST_PP_REPEAT_3_66(m, d) m(4, 66, d)
638
# define BOOST_PP_REPEAT_3_68(m, d) BOOST_PP_REPEAT_3_67(m, d) m(4, 67, d)
639
# define BOOST_PP_REPEAT_3_69(m, d) BOOST_PP_REPEAT_3_68(m, d) m(4, 68, d)
640
# define BOOST_PP_REPEAT_3_70(m, d) BOOST_PP_REPEAT_3_69(m, d) m(4, 69, d)
641
# define BOOST_PP_REPEAT_3_71(m, d) BOOST_PP_REPEAT_3_70(m, d) m(4, 70, d)
642
# define BOOST_PP_REPEAT_3_72(m, d) BOOST_PP_REPEAT_3_71(m, d) m(4, 71, d)
643
# define BOOST_PP_REPEAT_3_73(m, d) BOOST_PP_REPEAT_3_72(m, d) m(4, 72, d)
644
# define BOOST_PP_REPEAT_3_74(m, d) BOOST_PP_REPEAT_3_73(m, d) m(4, 73, d)
645
# define BOOST_PP_REPEAT_3_75(m, d) BOOST_PP_REPEAT_3_74(m, d) m(4, 74, d)
646
# define BOOST_PP_REPEAT_3_76(m, d) BOOST_PP_REPEAT_3_75(m, d) m(4, 75, d)
647
# define BOOST_PP_REPEAT_3_77(m, d) BOOST_PP_REPEAT_3_76(m, d) m(4, 76, d)
648
# define BOOST_PP_REPEAT_3_78(m, d) BOOST_PP_REPEAT_3_77(m, d) m(4, 77, d)
649
# define BOOST_PP_REPEAT_3_79(m, d) BOOST_PP_REPEAT_3_78(m, d) m(4, 78, d)
650
# define BOOST_PP_REPEAT_3_80(m, d) BOOST_PP_REPEAT_3_79(m, d) m(4, 79, d)
651
# define BOOST_PP_REPEAT_3_81(m, d) BOOST_PP_REPEAT_3_80(m, d) m(4, 80, d)
652
# define BOOST_PP_REPEAT_3_82(m, d) BOOST_PP_REPEAT_3_81(m, d) m(4, 81, d)
653
# define BOOST_PP_REPEAT_3_83(m, d) BOOST_PP_REPEAT_3_82(m, d) m(4, 82, d)
654
# define BOOST_PP_REPEAT_3_84(m, d) BOOST_PP_REPEAT_3_83(m, d) m(4, 83, d)
655
# define BOOST_PP_REPEAT_3_85(m, d) BOOST_PP_REPEAT_3_84(m, d) m(4, 84, d)
656
# define BOOST_PP_REPEAT_3_86(m, d) BOOST_PP_REPEAT_3_85(m, d) m(4, 85, d)
657
# define BOOST_PP_REPEAT_3_87(m, d) BOOST_PP_REPEAT_3_86(m, d) m(4, 86, d)
658
# define BOOST_PP_REPEAT_3_88(m, d) BOOST_PP_REPEAT_3_87(m, d) m(4, 87, d)
659
# define BOOST_PP_REPEAT_3_89(m, d) BOOST_PP_REPEAT_3_88(m, d) m(4, 88, d)
660
# define BOOST_PP_REPEAT_3_90(m, d) BOOST_PP_REPEAT_3_89(m, d) m(4, 89, d)
661
# define BOOST_PP_REPEAT_3_91(m, d) BOOST_PP_REPEAT_3_90(m, d) m(4, 90, d)
662
# define BOOST_PP_REPEAT_3_92(m, d) BOOST_PP_REPEAT_3_91(m, d) m(4, 91, d)
663
# define BOOST_PP_REPEAT_3_93(m, d) BOOST_PP_REPEAT_3_92(m, d) m(4, 92, d)
664
# define BOOST_PP_REPEAT_3_94(m, d) BOOST_PP_REPEAT_3_93(m, d) m(4, 93, d)
665
# define BOOST_PP_REPEAT_3_95(m, d) BOOST_PP_REPEAT_3_94(m, d) m(4, 94, d)
666
# define BOOST_PP_REPEAT_3_96(m, d) BOOST_PP_REPEAT_3_95(m, d) m(4, 95, d)
667
# define BOOST_PP_REPEAT_3_97(m, d) BOOST_PP_REPEAT_3_96(m, d) m(4, 96, d)
668
# define BOOST_PP_REPEAT_3_98(m, d) BOOST_PP_REPEAT_3_97(m, d) m(4, 97, d)
669
# define BOOST_PP_REPEAT_3_99(m, d) BOOST_PP_REPEAT_3_98(m, d) m(4, 98, d)
670
# define BOOST_PP_REPEAT_3_100(m, d) BOOST_PP_REPEAT_3_99(m, d) m(4, 99, d)
671
# define BOOST_PP_REPEAT_3_101(m, d) BOOST_PP_REPEAT_3_100(m, d) m(4, 100, d)
672
# define BOOST_PP_REPEAT_3_102(m, d) BOOST_PP_REPEAT_3_101(m, d) m(4, 101, d)
673
# define BOOST_PP_REPEAT_3_103(m, d) BOOST_PP_REPEAT_3_102(m, d) m(4, 102, d)
674
# define BOOST_PP_REPEAT_3_104(m, d) BOOST_PP_REPEAT_3_103(m, d) m(4, 103, d)
675
# define BOOST_PP_REPEAT_3_105(m, d) BOOST_PP_REPEAT_3_104(m, d) m(4, 104, d)
676
# define BOOST_PP_REPEAT_3_106(m, d) BOOST_PP_REPEAT_3_105(m, d) m(4, 105, d)
677
# define BOOST_PP_REPEAT_3_107(m, d) BOOST_PP_REPEAT_3_106(m, d) m(4, 106, d)
678
# define BOOST_PP_REPEAT_3_108(m, d) BOOST_PP_REPEAT_3_107(m, d) m(4, 107, d)
679
# define BOOST_PP_REPEAT_3_109(m, d) BOOST_PP_REPEAT_3_108(m, d) m(4, 108, d)
680
# define BOOST_PP_REPEAT_3_110(m, d) BOOST_PP_REPEAT_3_109(m, d) m(4, 109, d)
681
# define BOOST_PP_REPEAT_3_111(m, d) BOOST_PP_REPEAT_3_110(m, d) m(4, 110, d)
682
# define BOOST_PP_REPEAT_3_112(m, d) BOOST_PP_REPEAT_3_111(m, d) m(4, 111, d)
683
# define BOOST_PP_REPEAT_3_113(m, d) BOOST_PP_REPEAT_3_112(m, d) m(4, 112, d)
684
# define BOOST_PP_REPEAT_3_114(m, d) BOOST_PP_REPEAT_3_113(m, d) m(4, 113, d)
685
# define BOOST_PP_REPEAT_3_115(m, d) BOOST_PP_REPEAT_3_114(m, d) m(4, 114, d)
686
# define BOOST_PP_REPEAT_3_116(m, d) BOOST_PP_REPEAT_3_115(m, d) m(4, 115, d)
687
# define BOOST_PP_REPEAT_3_117(m, d) BOOST_PP_REPEAT_3_116(m, d) m(4, 116, d)
688
# define BOOST_PP_REPEAT_3_118(m, d) BOOST_PP_REPEAT_3_117(m, d) m(4, 117, d)
689
# define BOOST_PP_REPEAT_3_119(m, d) BOOST_PP_REPEAT_3_118(m, d) m(4, 118, d)
690
# define BOOST_PP_REPEAT_3_120(m, d) BOOST_PP_REPEAT_3_119(m, d) m(4, 119, d)
691
# define BOOST_PP_REPEAT_3_121(m, d) BOOST_PP_REPEAT_3_120(m, d) m(4, 120, d)
692
# define BOOST_PP_REPEAT_3_122(m, d) BOOST_PP_REPEAT_3_121(m, d) m(4, 121, d)
693
# define BOOST_PP_REPEAT_3_123(m, d) BOOST_PP_REPEAT_3_122(m, d) m(4, 122, d)
694
# define BOOST_PP_REPEAT_3_124(m, d) BOOST_PP_REPEAT_3_123(m, d) m(4, 123, d)
695
# define BOOST_PP_REPEAT_3_125(m, d) BOOST_PP_REPEAT_3_124(m, d) m(4, 124, d)
696
# define BOOST_PP_REPEAT_3_126(m, d) BOOST_PP_REPEAT_3_125(m, d) m(4, 125, d)
697
# define BOOST_PP_REPEAT_3_127(m, d) BOOST_PP_REPEAT_3_126(m, d) m(4, 126, d)
698
# define BOOST_PP_REPEAT_3_128(m, d) BOOST_PP_REPEAT_3_127(m, d) m(4, 127, d)
699
# define BOOST_PP_REPEAT_3_129(m, d) BOOST_PP_REPEAT_3_128(m, d) m(4, 128, d)
700
# define BOOST_PP_REPEAT_3_130(m, d) BOOST_PP_REPEAT_3_129(m, d) m(4, 129, d)
701
# define BOOST_PP_REPEAT_3_131(m, d) BOOST_PP_REPEAT_3_130(m, d) m(4, 130, d)
702
# define BOOST_PP_REPEAT_3_132(m, d) BOOST_PP_REPEAT_3_131(m, d) m(4, 131, d)
703
# define BOOST_PP_REPEAT_3_133(m, d) BOOST_PP_REPEAT_3_132(m, d) m(4, 132, d)
704
# define BOOST_PP_REPEAT_3_134(m, d) BOOST_PP_REPEAT_3_133(m, d) m(4, 133, d)
705
# define BOOST_PP_REPEAT_3_135(m, d) BOOST_PP_REPEAT_3_134(m, d) m(4, 134, d)
706
# define BOOST_PP_REPEAT_3_136(m, d) BOOST_PP_REPEAT_3_135(m, d) m(4, 135, d)
707
# define BOOST_PP_REPEAT_3_137(m, d) BOOST_PP_REPEAT_3_136(m, d) m(4, 136, d)
708
# define BOOST_PP_REPEAT_3_138(m, d) BOOST_PP_REPEAT_3_137(m, d) m(4, 137, d)
709
# define BOOST_PP_REPEAT_3_139(m, d) BOOST_PP_REPEAT_3_138(m, d) m(4, 138, d)
710
# define BOOST_PP_REPEAT_3_140(m, d) BOOST_PP_REPEAT_3_139(m, d) m(4, 139, d)
711
# define BOOST_PP_REPEAT_3_141(m, d) BOOST_PP_REPEAT_3_140(m, d) m(4, 140, d)
712
# define BOOST_PP_REPEAT_3_142(m, d) BOOST_PP_REPEAT_3_141(m, d) m(4, 141, d)
713
# define BOOST_PP_REPEAT_3_143(m, d) BOOST_PP_REPEAT_3_142(m, d) m(4, 142, d)
714
# define BOOST_PP_REPEAT_3_144(m, d) BOOST_PP_REPEAT_3_143(m, d) m(4, 143, d)
715
# define BOOST_PP_REPEAT_3_145(m, d) BOOST_PP_REPEAT_3_144(m, d) m(4, 144, d)
716
# define BOOST_PP_REPEAT_3_146(m, d) BOOST_PP_REPEAT_3_145(m, d) m(4, 145, d)
717
# define BOOST_PP_REPEAT_3_147(m, d) BOOST_PP_REPEAT_3_146(m, d) m(4, 146, d)
718
# define BOOST_PP_REPEAT_3_148(m, d) BOOST_PP_REPEAT_3_147(m, d) m(4, 147, d)
719
# define BOOST_PP_REPEAT_3_149(m, d) BOOST_PP_REPEAT_3_148(m, d) m(4, 148, d)
720
# define BOOST_PP_REPEAT_3_150(m, d) BOOST_PP_REPEAT_3_149(m, d) m(4, 149, d)
721
# define BOOST_PP_REPEAT_3_151(m, d) BOOST_PP_REPEAT_3_150(m, d) m(4, 150, d)
722
# define BOOST_PP_REPEAT_3_152(m, d) BOOST_PP_REPEAT_3_151(m, d) m(4, 151, d)
723
# define BOOST_PP_REPEAT_3_153(m, d) BOOST_PP_REPEAT_3_152(m, d) m(4, 152, d)
724
# define BOOST_PP_REPEAT_3_154(m, d) BOOST_PP_REPEAT_3_153(m, d) m(4, 153, d)
725
# define BOOST_PP_REPEAT_3_155(m, d) BOOST_PP_REPEAT_3_154(m, d) m(4, 154, d)
726
# define BOOST_PP_REPEAT_3_156(m, d) BOOST_PP_REPEAT_3_155(m, d) m(4, 155, d)
727
# define BOOST_PP_REPEAT_3_157(m, d) BOOST_PP_REPEAT_3_156(m, d) m(4, 156, d)
728
# define BOOST_PP_REPEAT_3_158(m, d) BOOST_PP_REPEAT_3_157(m, d) m(4, 157, d)
729
# define BOOST_PP_REPEAT_3_159(m, d) BOOST_PP_REPEAT_3_158(m, d) m(4, 158, d)
730
# define BOOST_PP_REPEAT_3_160(m, d) BOOST_PP_REPEAT_3_159(m, d) m(4, 159, d)
731
# define BOOST_PP_REPEAT_3_161(m, d) BOOST_PP_REPEAT_3_160(m, d) m(4, 160, d)
732
# define BOOST_PP_REPEAT_3_162(m, d) BOOST_PP_REPEAT_3_161(m, d) m(4, 161, d)
733
# define BOOST_PP_REPEAT_3_163(m, d) BOOST_PP_REPEAT_3_162(m, d) m(4, 162, d)
734
# define BOOST_PP_REPEAT_3_164(m, d) BOOST_PP_REPEAT_3_163(m, d) m(4, 163, d)
735
# define BOOST_PP_REPEAT_3_165(m, d) BOOST_PP_REPEAT_3_164(m, d) m(4, 164, d)
736
# define BOOST_PP_REPEAT_3_166(m, d) BOOST_PP_REPEAT_3_165(m, d) m(4, 165, d)
737
# define BOOST_PP_REPEAT_3_167(m, d) BOOST_PP_REPEAT_3_166(m, d) m(4, 166, d)
738
# define BOOST_PP_REPEAT_3_168(m, d) BOOST_PP_REPEAT_3_167(m, d) m(4, 167, d)
739
# define BOOST_PP_REPEAT_3_169(m, d) BOOST_PP_REPEAT_3_168(m, d) m(4, 168, d)
740
# define BOOST_PP_REPEAT_3_170(m, d) BOOST_PP_REPEAT_3_169(m, d) m(4, 169, d)
741
# define BOOST_PP_REPEAT_3_171(m, d) BOOST_PP_REPEAT_3_170(m, d) m(4, 170, d)
742
# define BOOST_PP_REPEAT_3_172(m, d) BOOST_PP_REPEAT_3_171(m, d) m(4, 171, d)
743
# define BOOST_PP_REPEAT_3_173(m, d) BOOST_PP_REPEAT_3_172(m, d) m(4, 172, d)
744
# define BOOST_PP_REPEAT_3_174(m, d) BOOST_PP_REPEAT_3_173(m, d) m(4, 173, d)
745
# define BOOST_PP_REPEAT_3_175(m, d) BOOST_PP_REPEAT_3_174(m, d) m(4, 174, d)
746
# define BOOST_PP_REPEAT_3_176(m, d) BOOST_PP_REPEAT_3_175(m, d) m(4, 175, d)
747
# define BOOST_PP_REPEAT_3_177(m, d) BOOST_PP_REPEAT_3_176(m, d) m(4, 176, d)
748
# define BOOST_PP_REPEAT_3_178(m, d) BOOST_PP_REPEAT_3_177(m, d) m(4, 177, d)
749
# define BOOST_PP_REPEAT_3_179(m, d) BOOST_PP_REPEAT_3_178(m, d) m(4, 178, d)
750
# define BOOST_PP_REPEAT_3_180(m, d) BOOST_PP_REPEAT_3_179(m, d) m(4, 179, d)
751
# define BOOST_PP_REPEAT_3_181(m, d) BOOST_PP_REPEAT_3_180(m, d) m(4, 180, d)
752
# define BOOST_PP_REPEAT_3_182(m, d) BOOST_PP_REPEAT_3_181(m, d) m(4, 181, d)
753
# define BOOST_PP_REPEAT_3_183(m, d) BOOST_PP_REPEAT_3_182(m, d) m(4, 182, d)
754
# define BOOST_PP_REPEAT_3_184(m, d) BOOST_PP_REPEAT_3_183(m, d) m(4, 183, d)
755
# define BOOST_PP_REPEAT_3_185(m, d) BOOST_PP_REPEAT_3_184(m, d) m(4, 184, d)
756
# define BOOST_PP_REPEAT_3_186(m, d) BOOST_PP_REPEAT_3_185(m, d) m(4, 185, d)
757
# define BOOST_PP_REPEAT_3_187(m, d) BOOST_PP_REPEAT_3_186(m, d) m(4, 186, d)
758
# define BOOST_PP_REPEAT_3_188(m, d) BOOST_PP_REPEAT_3_187(m, d) m(4, 187, d)
759
# define BOOST_PP_REPEAT_3_189(m, d) BOOST_PP_REPEAT_3_188(m, d) m(4, 188, d)
760
# define BOOST_PP_REPEAT_3_190(m, d) BOOST_PP_REPEAT_3_189(m, d) m(4, 189, d)
761
# define BOOST_PP_REPEAT_3_191(m, d) BOOST_PP_REPEAT_3_190(m, d) m(4, 190, d)
762
# define BOOST_PP_REPEAT_3_192(m, d) BOOST_PP_REPEAT_3_191(m, d) m(4, 191, d)
763
# define BOOST_PP_REPEAT_3_193(m, d) BOOST_PP_REPEAT_3_192(m, d) m(4, 192, d)
764
# define BOOST_PP_REPEAT_3_194(m, d) BOOST_PP_REPEAT_3_193(m, d) m(4, 193, d)
765
# define BOOST_PP_REPEAT_3_195(m, d) BOOST_PP_REPEAT_3_194(m, d) m(4, 194, d)
766
# define BOOST_PP_REPEAT_3_196(m, d) BOOST_PP_REPEAT_3_195(m, d) m(4, 195, d)
767
# define BOOST_PP_REPEAT_3_197(m, d) BOOST_PP_REPEAT_3_196(m, d) m(4, 196, d)
768
# define BOOST_PP_REPEAT_3_198(m, d) BOOST_PP_REPEAT_3_197(m, d) m(4, 197, d)
769
# define BOOST_PP_REPEAT_3_199(m, d) BOOST_PP_REPEAT_3_198(m, d) m(4, 198, d)
770
# define BOOST_PP_REPEAT_3_200(m, d) BOOST_PP_REPEAT_3_199(m, d) m(4, 199, d)
771
# define BOOST_PP_REPEAT_3_201(m, d) BOOST_PP_REPEAT_3_200(m, d) m(4, 200, d)
772
# define BOOST_PP_REPEAT_3_202(m, d) BOOST_PP_REPEAT_3_201(m, d) m(4, 201, d)
773
# define BOOST_PP_REPEAT_3_203(m, d) BOOST_PP_REPEAT_3_202(m, d) m(4, 202, d)
774
# define BOOST_PP_REPEAT_3_204(m, d) BOOST_PP_REPEAT_3_203(m, d) m(4, 203, d)
775
# define BOOST_PP_REPEAT_3_205(m, d) BOOST_PP_REPEAT_3_204(m, d) m(4, 204, d)
776
# define BOOST_PP_REPEAT_3_206(m, d) BOOST_PP_REPEAT_3_205(m, d) m(4, 205, d)
777
# define BOOST_PP_REPEAT_3_207(m, d) BOOST_PP_REPEAT_3_206(m, d) m(4, 206, d)
778
# define BOOST_PP_REPEAT_3_208(m, d) BOOST_PP_REPEAT_3_207(m, d) m(4, 207, d)
779
# define BOOST_PP_REPEAT_3_209(m, d) BOOST_PP_REPEAT_3_208(m, d) m(4, 208, d)
780
# define BOOST_PP_REPEAT_3_210(m, d) BOOST_PP_REPEAT_3_209(m, d) m(4, 209, d)
781
# define BOOST_PP_REPEAT_3_211(m, d) BOOST_PP_REPEAT_3_210(m, d) m(4, 210, d)
782
# define BOOST_PP_REPEAT_3_212(m, d) BOOST_PP_REPEAT_3_211(m, d) m(4, 211, d)
783
# define BOOST_PP_REPEAT_3_213(m, d) BOOST_PP_REPEAT_3_212(m, d) m(4, 212, d)
784
# define BOOST_PP_REPEAT_3_214(m, d) BOOST_PP_REPEAT_3_213(m, d) m(4, 213, d)
785
# define BOOST_PP_REPEAT_3_215(m, d) BOOST_PP_REPEAT_3_214(m, d) m(4, 214, d)
786
# define BOOST_PP_REPEAT_3_216(m, d) BOOST_PP_REPEAT_3_215(m, d) m(4, 215, d)
787
# define BOOST_PP_REPEAT_3_217(m, d) BOOST_PP_REPEAT_3_216(m, d) m(4, 216, d)
788
# define BOOST_PP_REPEAT_3_218(m, d) BOOST_PP_REPEAT_3_217(m, d) m(4, 217, d)
789
# define BOOST_PP_REPEAT_3_219(m, d) BOOST_PP_REPEAT_3_218(m, d) m(4, 218, d)
790
# define BOOST_PP_REPEAT_3_220(m, d) BOOST_PP_REPEAT_3_219(m, d) m(4, 219, d)
791
# define BOOST_PP_REPEAT_3_221(m, d) BOOST_PP_REPEAT_3_220(m, d) m(4, 220, d)
792
# define BOOST_PP_REPEAT_3_222(m, d) BOOST_PP_REPEAT_3_221(m, d) m(4, 221, d)
793
# define BOOST_PP_REPEAT_3_223(m, d) BOOST_PP_REPEAT_3_222(m, d) m(4, 222, d)
794
# define BOOST_PP_REPEAT_3_224(m, d) BOOST_PP_REPEAT_3_223(m, d) m(4, 223, d)
795
# define BOOST_PP_REPEAT_3_225(m, d) BOOST_PP_REPEAT_3_224(m, d) m(4, 224, d)
796
# define BOOST_PP_REPEAT_3_226(m, d) BOOST_PP_REPEAT_3_225(m, d) m(4, 225, d)
797
# define BOOST_PP_REPEAT_3_227(m, d) BOOST_PP_REPEAT_3_226(m, d) m(4, 226, d)
798
# define BOOST_PP_REPEAT_3_228(m, d) BOOST_PP_REPEAT_3_227(m, d) m(4, 227, d)
799
# define BOOST_PP_REPEAT_3_229(m, d) BOOST_PP_REPEAT_3_228(m, d) m(4, 228, d)
800
# define BOOST_PP_REPEAT_3_230(m, d) BOOST_PP_REPEAT_3_229(m, d) m(4, 229, d)
801
# define BOOST_PP_REPEAT_3_231(m, d) BOOST_PP_REPEAT_3_230(m, d) m(4, 230, d)
802
# define BOOST_PP_REPEAT_3_232(m, d) BOOST_PP_REPEAT_3_231(m, d) m(4, 231, d)
803
# define BOOST_PP_REPEAT_3_233(m, d) BOOST_PP_REPEAT_3_232(m, d) m(4, 232, d)
804
# define BOOST_PP_REPEAT_3_234(m, d) BOOST_PP_REPEAT_3_233(m, d) m(4, 233, d)
805
# define BOOST_PP_REPEAT_3_235(m, d) BOOST_PP_REPEAT_3_234(m, d) m(4, 234, d)
806
# define BOOST_PP_REPEAT_3_236(m, d) BOOST_PP_REPEAT_3_235(m, d) m(4, 235, d)
807
# define BOOST_PP_REPEAT_3_237(m, d) BOOST_PP_REPEAT_3_236(m, d) m(4, 236, d)
808
# define BOOST_PP_REPEAT_3_238(m, d) BOOST_PP_REPEAT_3_237(m, d) m(4, 237, d)
809
# define BOOST_PP_REPEAT_3_239(m, d) BOOST_PP_REPEAT_3_238(m, d) m(4, 238, d)
810
# define BOOST_PP_REPEAT_3_240(m, d) BOOST_PP_REPEAT_3_239(m, d) m(4, 239, d)
811
# define BOOST_PP_REPEAT_3_241(m, d) BOOST_PP_REPEAT_3_240(m, d) m(4, 240, d)
812
# define BOOST_PP_REPEAT_3_242(m, d) BOOST_PP_REPEAT_3_241(m, d) m(4, 241, d)
813
# define BOOST_PP_REPEAT_3_243(m, d) BOOST_PP_REPEAT_3_242(m, d) m(4, 242, d)
814
# define BOOST_PP_REPEAT_3_244(m, d) BOOST_PP_REPEAT_3_243(m, d) m(4, 243, d)
815
# define BOOST_PP_REPEAT_3_245(m, d) BOOST_PP_REPEAT_3_244(m, d) m(4, 244, d)
816
# define BOOST_PP_REPEAT_3_246(m, d) BOOST_PP_REPEAT_3_245(m, d) m(4, 245, d)
817
# define BOOST_PP_REPEAT_3_247(m, d) BOOST_PP_REPEAT_3_246(m, d) m(4, 246, d)
818
# define BOOST_PP_REPEAT_3_248(m, d) BOOST_PP_REPEAT_3_247(m, d) m(4, 247, d)
819
# define BOOST_PP_REPEAT_3_249(m, d) BOOST_PP_REPEAT_3_248(m, d) m(4, 248, d)
820
# define BOOST_PP_REPEAT_3_250(m, d) BOOST_PP_REPEAT_3_249(m, d) m(4, 249, d)
821
# define BOOST_PP_REPEAT_3_251(m, d) BOOST_PP_REPEAT_3_250(m, d) m(4, 250, d)
822
# define BOOST_PP_REPEAT_3_252(m, d) BOOST_PP_REPEAT_3_251(m, d) m(4, 251, d)
823
# define BOOST_PP_REPEAT_3_253(m, d) BOOST_PP_REPEAT_3_252(m, d) m(4, 252, d)
824
# define BOOST_PP_REPEAT_3_254(m, d) BOOST_PP_REPEAT_3_253(m, d) m(4, 253, d)
825
# define BOOST_PP_REPEAT_3_255(m, d) BOOST_PP_REPEAT_3_254(m, d) m(4, 254, d)
826
# define BOOST_PP_REPEAT_3_256(m, d) BOOST_PP_REPEAT_3_255(m, d) m(4, 255, d)
827
#
828
# else
829
#
830
# include <boost/preprocessor/config/limits.hpp>
831
#
832
# if BOOST_PP_LIMIT_REPEAT == 256
833
# include <boost/preprocessor/repetition/limits/repeat_256.hpp>
834
# elif BOOST_PP_LIMIT_REPEAT == 512
835
# include <boost/preprocessor/repetition/limits/repeat_256.hpp>
836
# include <boost/preprocessor/repetition/limits/repeat_512.hpp>
837
# elif BOOST_PP_LIMIT_REPEAT == 1024
838
# include <boost/preprocessor/repetition/limits/repeat_256.hpp>
839
# include <boost/preprocessor/repetition/limits/repeat_512.hpp>
840
# include <boost/preprocessor/repetition/limits/repeat_1024.hpp>
841
# else
842
# error Incorrect value for the BOOST_PP_LIMIT_REPEAT limit
843
# endif
844
#
845
# endif
846
#
847
# endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/adaptor/copied.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Range library
2
//
3
//  Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and
4
//  distribution is subject to the Boost Software License, Version
5
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
11
#ifndef BOOST_RANGE_ADAPTOR_COPIED_HPP
12
#define BOOST_RANGE_ADAPTOR_COPIED_HPP
13
14
#include <boost/range/adaptor/argument_fwd.hpp>
15
#include <boost/range/adaptor/sliced.hpp>
16
#include <boost/range/size_type.hpp>
17
#include <boost/range/iterator_range.hpp>
18
#include <boost/range/concepts.hpp>
19
20
namespace boost
21
{
22
    namespace adaptors
23
    {
24
        struct copied
25
        {
26
            copied(std::size_t t_, std::size_t u_)
27
0
                : t(t_), u(u_) {}
28
29
            std::size_t t;
30
            std::size_t u;
31
        };
32
33
        template<class CopyableRandomAccessRange>
34
        inline CopyableRandomAccessRange
35
        operator|(const CopyableRandomAccessRange& r, const copied& f)
36
        {
37
            BOOST_RANGE_CONCEPT_ASSERT((
38
                RandomAccessRangeConcept<const CopyableRandomAccessRange>));
39
40
            iterator_range<
41
                BOOST_DEDUCED_TYPENAME range_iterator<
42
                    const CopyableRandomAccessRange
43
                >::type
44
            > temp(adaptors::slice(r, f.t, f.u));
45
46
            return CopyableRandomAccessRange(temp.begin(), temp.end());
47
        }
48
49
        template<class CopyableRandomAccessRange>
50
        inline CopyableRandomAccessRange
51
        copy(const CopyableRandomAccessRange& rng, std::size_t t, std::size_t u)
52
        {
53
            BOOST_RANGE_CONCEPT_ASSERT((
54
                RandomAccessRangeConcept<const CopyableRandomAccessRange>));
55
56
            iterator_range<
57
                BOOST_DEDUCED_TYPENAME range_iterator<
58
                    const CopyableRandomAccessRange
59
                >::type
60
            > temp(adaptors::slice(rng, t, u));
61
62
            return CopyableRandomAccessRange( temp.begin(), temp.end() );
63
        }
64
    } // 'adaptors'
65
66
}
67
68
#endif // include guard
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/adaptor/formatted.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Range library
2
//
3
//  Copyright Neil Groves 2014.
4
//  Use, modification and distribution is subject to the Boost Software
5
//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
#ifndef BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
11
#define BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
12
13
#include <boost/config.hpp>
14
#include <boost/range/concepts.hpp>
15
#include <boost/range/begin.hpp>
16
#include <boost/range/end.hpp>
17
#include <boost/range/iterator.hpp>
18
#include <boost/range/iterator_range_core.hpp>
19
#include <boost/mpl/if.hpp>
20
#include <boost/type_traits/is_array.hpp>
21
#include <boost/type_traits/remove_extent.hpp>
22
#include <ostream>
23
24
namespace boost
25
{
26
    namespace range_detail
27
    {
28
29
template<typename Sep, typename Prefix, typename Postfix>
30
struct formatted_holder
31
{
32
    typedef typename boost::mpl::if_<
33
        boost::is_array<Sep>,
34
        const typename boost::remove_extent<Sep>::type*,
35
        Sep
36
    >::type separator_t;
37
38
    typedef typename boost::mpl::if_<
39
        boost::is_array<Prefix>,
40
        const typename boost::remove_extent<Prefix>::type*,
41
        Prefix
42
    >::type prefix_t;
43
44
    typedef typename boost::mpl::if_<
45
        boost::is_array<Postfix>,
46
        const typename boost::remove_extent<Postfix>::type*,
47
        Postfix
48
    >::type postfix_t;
49
50
    formatted_holder(
51
        const separator_t& sep,
52
        const prefix_t& prefix,
53
        const postfix_t& postfix)
54
        : m_sep(sep)
55
        , m_prefix(prefix)
56
        , m_postfix(postfix)
57
    {
58
    }
59
60
    separator_t m_sep;
61
    prefix_t m_prefix;
62
    postfix_t m_postfix;
63
};
64
65
template<typename Iter, typename Sep, typename Prefix, typename Postfix>
66
class formatted_range
67
        : public boost::iterator_range<Iter>
68
{
69
    typedef formatted_holder<Sep,Prefix,Postfix> holder_t;
70
public:
71
    formatted_range(Iter first, Iter last, const holder_t& holder)
72
        : boost::iterator_range<Iter>(first, last)
73
        , m_holder(holder)
74
    {
75
    }
76
77
    template<typename OStream>
78
    void write(OStream& out) const
79
    {
80
        Iter it(this->begin());
81
        out << m_holder.m_prefix;
82
        if (it != this->end())
83
        {
84
            out << *it;
85
            for (++it; it != this->end(); ++it)
86
            {
87
                out << m_holder.m_sep << *it;
88
            }
89
        }
90
        out << m_holder.m_postfix;
91
    }
92
93
private:
94
    holder_t m_holder;
95
};
96
97
template<
98
    typename SinglePassRange,
99
    typename Sep,
100
    typename Prefix,
101
    typename Postfix
102
>
103
inline range_detail::formatted_range<
104
    typename range_iterator<const SinglePassRange>::type, Sep, Prefix, Postfix
105
>
106
operator|(
107
    const SinglePassRange& rng,
108
    const range_detail::formatted_holder<Sep,Prefix,Postfix>& holder
109
)
110
{
111
    typedef typename range_iterator<const SinglePassRange>::type iterator;
112
    return range_detail::formatted_range<iterator, Sep, Prefix, Postfix>(
113
        boost::begin(rng), boost::end(rng), holder);
114
}
115
116
template<typename Char, typename Traits, typename Iter, typename Sep,
117
    typename Prefix, typename Postfix>
118
std::basic_ostream<Char, Traits>&
119
operator<<(
120
        std::basic_ostream<Char, Traits>& out,
121
        const formatted_range<Iter, Sep, Prefix, Postfix>& writer)
122
{
123
    writer.write(out);
124
    return out;
125
}
126
127
    } // namespace range_detail
128
129
    namespace adaptors
130
    {
131
132
template<typename Sep, typename Prefix, typename Postfix>
133
range_detail::formatted_holder<Sep, Prefix, Postfix>
134
formatted(const Sep& sep, const Prefix& prefix, const Postfix& postfix)
135
{
136
    return range_detail::formatted_holder<Sep,Prefix,Postfix>(
137
                sep, prefix, postfix);
138
}
139
140
template<typename Sep, typename Prefix>
141
range_detail::formatted_holder<Sep, Prefix, char>
142
formatted(const Sep& sep, const Prefix& prefix)
143
{
144
    return range_detail::formatted_holder<Sep, Prefix, char>(sep, prefix, '}');
145
}
146
147
template<typename Sep>
148
range_detail::formatted_holder<Sep, char, char>
149
formatted(const Sep& sep)
150
{
151
    return range_detail::formatted_holder<Sep, char, char>(sep, '{', '}');
152
}
153
154
inline range_detail::formatted_holder<char, char, char>
155
formatted()
156
0
{
157
0
    return range_detail::formatted_holder<char, char, char>(',', '{', '}');
158
0
}
159
160
using range_detail::formatted_range;
161
162
template<typename SinglePassRange, typename Sep, typename Prefix,
163
         typename Postfix>
164
inline boost::range_detail::formatted_range<
165
    typename boost::range_iterator<const SinglePassRange>::type,
166
    Sep, Prefix, Postfix
167
>
168
format(
169
    const SinglePassRange& rng,
170
    const Sep& sep,
171
    const Prefix& prefix,
172
    const Postfix& postfix
173
)
174
{
175
    typedef typename boost::range_iterator<const SinglePassRange>::type
176
                iterator_t;
177
178
    typedef boost::range_detail::formatted_range<
179
                iterator_t, Sep, Prefix, Postfix>       result_t;
180
181
    typedef boost::range_detail::formatted_holder<Sep, Prefix, Postfix>
182
                holder_t;
183
184
    return result_t(boost::begin(rng), boost::end(rng),
185
                    holder_t(sep, prefix, postfix));
186
}
187
188
template<typename SinglePassRange, typename Sep, typename Prefix>
189
inline boost::range_detail::formatted_range<
190
    typename boost::range_iterator<const SinglePassRange>::type,
191
    Sep, Prefix, char
192
>
193
format(
194
    const SinglePassRange& rng,
195
    const Sep& sep,
196
    const Prefix& prefix)
197
{
198
    return adaptors::format<SinglePassRange, Sep, Prefix, char>(rng, sep, prefix, '}');
199
}
200
201
template<typename SinglePassRange, typename Sep>
202
inline boost::range_detail::formatted_range<
203
    typename boost::range_iterator<const SinglePassRange>::type,
204
    Sep, char, char
205
>
206
format(const SinglePassRange& rng, const Sep& sep)
207
{
208
    return adaptors::format<SinglePassRange, Sep, char, char>(rng, sep, '{', '}');
209
}
210
211
template<typename SinglePassRange>
212
inline boost::range_detail::formatted_range<
213
    typename boost::range_iterator<const SinglePassRange>::type,
214
    char, char, char
215
>
216
format(const SinglePassRange& rng)
217
{
218
    return adaptors::format<SinglePassRange, char, char, char>(rng, ',', '{', '}');
219
}
220
221
    } // namespace adaptors
222
223
    namespace range
224
    {
225
        using boost::range_detail::formatted_range;
226
    } // namespace range
227
} // namespace boost
228
229
#endif // include guard
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/adaptor/indexed.hpp
Line
Count
Source (jump to first uncovered line)
1
//  Copyright 2014 Neil Groves
2
//
3
//  Copyright (c) 2010 Ilya Murav'jov
4
// 
5
//  Use, modification and distribution is subject to the Boost Software License,
6
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7
//  http://www.boost.org/LICENSE_1_0.txt)
8
//
9
// Credits:
10
//  My (Neil's) first indexed adaptor was hindered by having the underlying
11
//  iterator return the same reference as the wrapped iterator. This meant that
12
//  to obtain the index one had to get to the index_iterator and call the
13
//  index() function on it. Ilya politely pointed out that this was useless in
14
//  a number of scenarios since one naturally hides the use of iterators in
15
//  good range-based code. Ilya provided a new interface (which has remained)
16
//  and a first implementation. Much of this original implementation has
17
//  been simplified and now supports more compilers and platforms.
18
//
19
#ifndef BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED
20
#define BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED
21
22
#include <boost/range/config.hpp>
23
#include <boost/range/adaptor/argument_fwd.hpp>
24
#include <boost/range/iterator_range.hpp>
25
#include <boost/range/traversal.hpp>
26
#include <boost/range/size.hpp>
27
#include <boost/range/begin.hpp>
28
#include <boost/range/end.hpp>
29
#include <boost/mpl/if.hpp>
30
#include <boost/type_traits/is_convertible.hpp>
31
32
#include <boost/iterator/iterator_traits.hpp>
33
#include <boost/iterator/iterator_facade.hpp>
34
35
#include <boost/tuple/tuple.hpp>
36
37
namespace boost
38
{
39
    namespace adaptors
40
    {
41
42
struct indexed
43
{
44
    explicit indexed(std::ptrdiff_t x = 0)
45
        : val(x)
46
0
    {
47
0
    }
48
    std::ptrdiff_t val;
49
};
50
51
    } // namespace adaptors
52
53
    namespace range
54
    {
55
56
// Why yet another "pair" class:
57
// - std::pair can't store references
58
// - no need for typing for index type (default to "std::ptrdiff_t"); this is
59
// useful in BOOST_FOREACH() expressions that have pitfalls with commas
60
//   ( see http://www.boost.org/doc/libs/1_44_0/doc/html/foreach/pitfalls.html )
61
// - meaningful access functions index(), value()
62
template<class T, class Indexable = std::ptrdiff_t>
63
class index_value
64
    : public tuple<Indexable, T>
65
{
66
    typedef tuple<Indexable, T> base_t;
67
68
    template<int N>
69
    struct iv_types
70
    {
71
        typedef typename tuples::element<N, base_t>::type n_type;
72
73
        typedef typename tuples::access_traits<n_type>::non_const_type non_const_type;
74
        typedef typename tuples::access_traits<n_type>::const_type const_type;
75
    };
76
77
public:
78
    typedef typename iv_types<0>::non_const_type index_type;
79
    typedef typename iv_types<0>::const_type const_index_type;
80
    typedef typename iv_types<1>::non_const_type value_type;
81
    typedef typename iv_types<1>::const_type const_value_type;
82
83
    index_value()
84
    {
85
    }
86
87
    index_value(typename tuples::access_traits<Indexable>::parameter_type t0,
88
                typename tuples::access_traits<T>::parameter_type t1)
89
        : base_t(t0, t1)
90
    {
91
    }
92
93
    // member functions index(), value() (non-const and const)
94
    index_type index()
95
    {
96
        return boost::tuples::get<0>(*this);
97
    }
98
99
    const_index_type index() const
100
    {
101
        return boost::tuples::get<0>(*this);
102
    }
103
104
    value_type value()
105
    {
106
        return boost::tuples::get<1>(*this);
107
    }
108
109
    const_value_type value() const
110
    {
111
        return boost::tuples::get<1>(*this);
112
    }
113
};
114
115
    } // namespace range
116
117
namespace range_detail
118
{
119
120
template<typename Iter>
121
struct indexed_iterator_value_type
122
{
123
    typedef ::boost::range::index_value<
124
        typename iterator_reference<Iter>::type,
125
        typename iterator_difference<Iter>::type
126
    > type;
127
};
128
129
// Meta-function to get the traversal for the range and therefore iterator
130
// returned by the indexed adaptor for a specified iterator type.
131
//
132
// Random access -> Random access
133
// Bidirectional -> Forward
134
// Forward -> Forward
135
// SinglePass -> SinglePass
136
//
137
// The rationale for demoting a Bidirectional input to Forward is that the end
138
// iterator cannot cheaply have an index computed for it. Therefore I chose to
139
// demote to forward traversal. I can maintain the ability to traverse randomly
140
// when the input is Random Access since the index for the end iterator is cheap
141
// to compute.
142
template<typename Iter>
143
struct indexed_traversal
144
{
145
private:
146
    typedef typename iterator_traversal<Iter>::type wrapped_traversal;
147
148
public:
149
150
    typedef typename mpl::if_<
151
        is_convertible<wrapped_traversal, random_access_traversal_tag>,
152
        random_access_traversal_tag,
153
        typename mpl::if_<
154
            is_convertible<wrapped_traversal, bidirectional_traversal_tag>,
155
            forward_traversal_tag,
156
            wrapped_traversal
157
        >::type
158
    >::type type;
159
};
160
161
template<typename Iter>
162
class indexed_iterator
163
    : public iterator_facade<
164
            indexed_iterator<Iter>,
165
            typename indexed_iterator_value_type<Iter>::type,
166
            typename indexed_traversal<Iter>::type,
167
            typename indexed_iterator_value_type<Iter>::type,
168
            typename iterator_difference<Iter>::type
169
        >
170
{
171
public:
172
    typedef Iter wrapped;
173
174
private:
175
    typedef iterator_facade<
176
        indexed_iterator<wrapped>,
177
        typename indexed_iterator_value_type<wrapped>::type,
178
        typename indexed_traversal<wrapped>::type,
179
        typename indexed_iterator_value_type<wrapped>::type,
180
        typename iterator_difference<wrapped>::type
181
    > base_t;
182
183
public:
184
    typedef typename base_t::difference_type difference_type;
185
    typedef typename base_t::reference reference;
186
    typedef typename base_t::difference_type index_type;
187
188
    indexed_iterator()
189
        : m_it()
190
        , m_index()
191
    {
192
    }
193
194
    template<typename OtherWrapped>
195
    indexed_iterator(
196
        const indexed_iterator<OtherWrapped>& other,
197
        typename enable_if<is_convertible<OtherWrapped, wrapped> >::type* = 0
198
    )
199
        : m_it(other.get())
200
        , m_index(other.get_index())
201
    {
202
    }
203
204
    explicit indexed_iterator(wrapped it, index_type index)
205
        : m_it(it)
206
        , m_index(index)
207
    {
208
    }
209
210
    wrapped get() const
211
    {
212
        return m_it;
213
    }
214
215
    index_type get_index() const
216
    {
217
        return m_index;
218
    }
219
220
 private:
221
    friend class boost::iterator_core_access;
222
223
    reference dereference() const
224
    {
225
        return reference(m_index, *m_it);
226
    }
227
228
    bool equal(const indexed_iterator& other) const
229
    {
230
        return m_it == other.m_it;
231
    }
232
233
    void increment()
234
    {
235
        ++m_index;
236
        ++m_it;
237
    }
238
239
    void decrement()
240
    {
241
        BOOST_ASSERT_MSG(m_index > 0, "indexed Iterator out of bounds");
242
        --m_index;
243
        --m_it;
244
    }
245
246
    void advance(index_type n)
247
    {
248
        m_index += n;
249
        BOOST_ASSERT_MSG(m_index >= 0, "indexed Iterator out of bounds");
250
        m_it += n;
251
    }
252
253
    difference_type distance_to(const indexed_iterator& other) const
254
    {
255
        return other.m_it - m_it;
256
    }
257
258
    wrapped m_it;
259
    index_type m_index;
260
};
261
262
template<typename SinglePassRange>
263
struct indexed_range
264
    : iterator_range<
265
        indexed_iterator<
266
            typename range_iterator<SinglePassRange>::type
267
        >
268
    >
269
{
270
    typedef iterator_range<
271
        indexed_iterator<
272
            typename range_iterator<SinglePassRange>::type
273
        >
274
    > base_t;
275
276
    BOOST_RANGE_CONCEPT_ASSERT((
277
        boost::SinglePassRangeConcept<SinglePassRange>));
278
public:
279
    typedef indexed_iterator<
280
        typename range_iterator<SinglePassRange>::type
281
    > iterator;
282
283
    // Constructor for non-random access iterators.
284
    // This sets the end iterator index to i despite this being incorrect it
285
    // is never observable since bidirectional iterators are demoted to
286
    // forward iterators.
287
    indexed_range(
288
        typename base_t::difference_type i,
289
        SinglePassRange& r,
290
        single_pass_traversal_tag
291
        )
292
        : base_t(iterator(boost::begin(r), i),
293
                 iterator(boost::end(r), i))
294
    {
295
    }
296
297
    indexed_range(
298
        typename base_t::difference_type i,
299
        SinglePassRange& r,
300
        random_access_traversal_tag
301
        )
302
        : base_t(iterator(boost::begin(r), i),
303
                 iterator(boost::end(r), i + boost::size(r)))
304
    {
305
    }
306
};
307
308
    } // namespace range_detail 
309
310
    using range_detail::indexed_range;
311
312
    namespace adaptors
313
    {
314
315
template<class SinglePassRange>
316
inline indexed_range<SinglePassRange>
317
operator|(SinglePassRange& r, indexed e)
318
{
319
    BOOST_RANGE_CONCEPT_ASSERT((
320
        boost::SinglePassRangeConcept<SinglePassRange>
321
    ));
322
    return indexed_range<SinglePassRange>(
323
                e.val, r,
324
                typename range_traversal<SinglePassRange>::type());
325
}
326
327
template<class SinglePassRange>
328
inline indexed_range<const SinglePassRange>
329
operator|(const SinglePassRange& r, indexed e)
330
{
331
    BOOST_RANGE_CONCEPT_ASSERT((
332
        boost::SinglePassRangeConcept<const SinglePassRange>
333
    ));
334
    return indexed_range<const SinglePassRange>(
335
                e.val, r,
336
                typename range_traversal<const SinglePassRange>::type());
337
}
338
339
template<class SinglePassRange>
340
inline indexed_range<SinglePassRange>
341
index(
342
    SinglePassRange& rng,
343
    typename range_difference<SinglePassRange>::type index_value = 0)
344
{
345
    BOOST_RANGE_CONCEPT_ASSERT((
346
        boost::SinglePassRangeConcept<SinglePassRange>
347
    ));
348
    return indexed_range<SinglePassRange>(
349
                index_value, rng,
350
                typename range_traversal<SinglePassRange>::type());
351
}
352
353
template<class SinglePassRange>
354
inline indexed_range<const SinglePassRange>
355
index(
356
    const SinglePassRange& rng,
357
    typename range_difference<const SinglePassRange>::type index_value = 0)
358
{
359
    BOOST_RANGE_CONCEPT_ASSERT((
360
        boost::SinglePassRangeConcept<SinglePassRange>
361
    ));
362
    return indexed_range<const SinglePassRange>(
363
                index_value, rng,
364
                typename range_traversal<const SinglePassRange>::type());
365
}
366
367
    } // namespace adaptors
368
} // namespace boost
369
370
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
371
372
namespace std {
373
374
#if defined(BOOST_CLANG)
375
#pragma clang diagnostic push
376
#pragma clang diagnostic ignored "-Wmismatched-tags"
377
#endif
378
379
template<size_t N, class T, class Indexable>
380
struct tuple_element<N, boost::range::index_value<T, Indexable>>:
381
    boost::tuples::element<N, boost::range::index_value<T, Indexable>> {};
382
383
template<class T, class Indexable>
384
struct tuple_size<boost::range::index_value<T, Indexable>>:
385
    std::integral_constant<std::size_t, 2> {};
386
387
#if defined(BOOST_CLANG)
388
#pragma clang diagnostic pop
389
#endif
390
391
} // namespace std
392
393
#endif // !defined(BOOST_NO_CXX11_HDR_TUPLE)
394
395
#endif // include guard
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/adaptor/sliced.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Range library
2
//
3
//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
4
//  distribution is subject to the Boost Software License, Version
5
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
11
#ifndef BOOST_RANGE_ADAPTOR_SLICED_HPP
12
#define BOOST_RANGE_ADAPTOR_SLICED_HPP
13
14
#include <boost/range/adaptor/argument_fwd.hpp>
15
#include <boost/range/size_type.hpp>
16
#include <boost/range/iterator_range.hpp>
17
#include <boost/range/concepts.hpp>
18
#include <boost/next_prior.hpp>
19
20
namespace boost
21
{
22
    namespace adaptors
23
    {
24
        struct sliced
25
        {
26
            sliced(std::size_t t_, std::size_t u_)
27
0
                : t(t_), u(u_) {}
28
            std::size_t t;
29
            std::size_t u;
30
        };
31
32
        template< class RandomAccessRange >
33
        class sliced_range : public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type >
34
        {
35
            typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type > base_t;
36
        public:
37
            template<typename Rng, typename T, typename U>
38
            sliced_range(Rng& rng, T t, U u)
39
                : base_t(boost::next(boost::begin(rng), t),
40
                         boost::next(boost::begin(rng), u))
41
            {
42
            }
43
        };
44
45
        template< class RandomAccessRange >
46
        inline sliced_range<RandomAccessRange>
47
        slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
48
        {
49
            BOOST_RANGE_CONCEPT_ASSERT((
50
                RandomAccessRangeConcept<RandomAccessRange>));
51
52
            BOOST_ASSERT( t <= u && "error in slice indices" );
53
            BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
54
                          "second slice index out of bounds" );
55
56
            return sliced_range<RandomAccessRange>(rng, t, u);
57
        }
58
59
        template< class RandomAccessRange >
60
        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type >
61
        slice( const RandomAccessRange& rng, std::size_t t, std::size_t u )
62
        {
63
            BOOST_RANGE_CONCEPT_ASSERT((
64
                RandomAccessRangeConcept<const RandomAccessRange>));
65
66
            BOOST_ASSERT( t <= u && "error in slice indices" );
67
            BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
68
                          "second slice index out of bounds" );
69
70
            return sliced_range<const RandomAccessRange>(rng, t, u);
71
        }
72
73
        template< class RandomAccessRange >
74
        inline sliced_range<RandomAccessRange>
75
        operator|( RandomAccessRange& r, const sliced& f )
76
        {
77
            BOOST_RANGE_CONCEPT_ASSERT((
78
                RandomAccessRangeConcept<RandomAccessRange>));
79
80
            return sliced_range<RandomAccessRange>( r, f.t, f.u );
81
        }
82
83
        template< class RandomAccessRange >
84
        inline sliced_range<const RandomAccessRange>
85
        operator|( const RandomAccessRange& r, const sliced& f )
86
        {
87
            BOOST_RANGE_CONCEPT_ASSERT((
88
                RandomAccessRangeConcept<const RandomAccessRange>));
89
90
            return sliced_range<const RandomAccessRange>( r, f.t, f.u );
91
        }
92
93
    } // namespace adaptors
94
    using adaptors::sliced_range;
95
} // namespace boost
96
97
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/algorithm/equal.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Range library
2
//
3
//  Copyright Neil Groves 2009.
4
//  Use, modification and distribution is subject to the Boost Software
5
//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
#ifndef BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
11
#define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
12
13
#include <boost/config.hpp>
14
#include <boost/range/concepts.hpp>
15
#include <iterator>
16
17
namespace boost
18
{
19
    namespace range_detail
20
    {
21
        // An implementation of equality comparison that is optimized for iterator
22
        // traversal categories less than RandomAccessTraversal.
23
        template< class SinglePassTraversalReadableIterator1,
24
                  class SinglePassTraversalReadableIterator2,
25
                  class IteratorCategoryTag1,
26
                  class IteratorCategoryTag2 >
27
        inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
28
                                SinglePassTraversalReadableIterator1 last1,
29
                                SinglePassTraversalReadableIterator2 first2,
30
                                SinglePassTraversalReadableIterator2 last2,
31
                                IteratorCategoryTag1,
32
                                IteratorCategoryTag2 )
33
        {
34
            for (;;)
35
            {
36
                // If we have reached the end of the left range then this is
37
                // the end of the loop. They are equal if and only if we have
38
                // simultaneously reached the end of the right range.
39
                if (first1 == last1)
40
                    return first2 == last2;
41
42
                // If we have reached the end of the right range at this line
43
                // it indicates that the right range is shorter than the left
44
                // and hence the result is false.
45
                if (first2 == last2)
46
                    return false;
47
48
                // continue looping if and only if the values are equal
49
                if (*first1 != *first2)
50
                    break;
51
52
                ++first1;
53
                ++first2;
54
            }
55
56
            // Reaching this line in the algorithm indicates that a value
57
            // inequality has been detected.
58
            return false;
59
        }
60
61
        template< class SinglePassTraversalReadableIterator1,
62
                  class SinglePassTraversalReadableIterator2,
63
                  class IteratorCategoryTag1,
64
                  class IteratorCategoryTag2,
65
                  class BinaryPredicate >
66
        inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
67
                                SinglePassTraversalReadableIterator1 last1,
68
                                SinglePassTraversalReadableIterator2 first2,
69
                                SinglePassTraversalReadableIterator2 last2,
70
                                BinaryPredicate                      pred,
71
                                IteratorCategoryTag1,
72
                                IteratorCategoryTag2 )
73
        {
74
            for (;;)
75
            {
76
                // If we have reached the end of the left range then this is
77
                // the end of the loop. They are equal if and only if we have
78
                // simultaneously reached the end of the right range.
79
                if (first1 == last1)
80
                    return first2 == last2;
81
82
                // If we have reached the end of the right range at this line
83
                // it indicates that the right range is shorter than the left
84
                // and hence the result is false.
85
                if (first2 == last2)
86
                    return false;
87
88
                // continue looping if and only if the values are equal
89
                if (!pred(*first1, *first2))
90
                    break;
91
92
                ++first1;
93
                ++first2;
94
            }
95
96
            // Reaching this line in the algorithm indicates that a value
97
            // inequality has been detected.
98
            return false;
99
        }
100
101
        // An implementation of equality comparison that is optimized for
102
        // random access iterators.
103
        template< class RandomAccessTraversalReadableIterator1,
104
                  class RandomAccessTraversalReadableIterator2 >
105
        inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
106
                                RandomAccessTraversalReadableIterator1 last1,
107
                                RandomAccessTraversalReadableIterator2 first2,
108
                                RandomAccessTraversalReadableIterator2 last2,
109
                                std::random_access_iterator_tag,
110
                                std::random_access_iterator_tag )
111
0
        {
112
0
            return ((last1 - first1) == (last2 - first2))
113
0
                && std::equal(first1, last1, first2);
114
0
        }
115
116
        template< class RandomAccessTraversalReadableIterator1,
117
                  class RandomAccessTraversalReadableIterator2,
118
                  class BinaryPredicate >
119
        inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
120
                                RandomAccessTraversalReadableIterator1 last1,
121
                                RandomAccessTraversalReadableIterator2 first2,
122
                                RandomAccessTraversalReadableIterator2 last2,
123
                                BinaryPredicate                        pred,
124
                                std::random_access_iterator_tag,
125
                                std::random_access_iterator_tag )
126
        {
127
            return ((last1 - first1) == (last2 - first2))
128
                && std::equal(first1, last1, first2, pred);
129
        }
130
131
        template< class SinglePassTraversalReadableIterator1,
132
                  class SinglePassTraversalReadableIterator2 >
133
        inline bool equal( SinglePassTraversalReadableIterator1 first1,
134
                           SinglePassTraversalReadableIterator1 last1,
135
                           SinglePassTraversalReadableIterator2 first2,
136
                           SinglePassTraversalReadableIterator2 last2 )
137
0
        {
138
0
            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
139
0
            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
140
141
0
            return equal_impl(first1, last1, first2, last2, tag1, tag2);
142
0
        }
143
144
        template< class SinglePassTraversalReadableIterator1,
145
                  class SinglePassTraversalReadableIterator2,
146
                  class BinaryPredicate >
147
        inline bool equal( SinglePassTraversalReadableIterator1 first1,
148
                           SinglePassTraversalReadableIterator1 last1,
149
                           SinglePassTraversalReadableIterator2 first2,
150
                           SinglePassTraversalReadableIterator2 last2,
151
                           BinaryPredicate                      pred )
152
        {
153
            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
154
            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
155
156
            return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
157
        }
158
159
    } // namespace range_detail
160
161
    namespace range
162
    {
163
164
        /// \brief template function equal
165
        ///
166
        /// range-based version of the equal std algorithm
167
        ///
168
        /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
169
        /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
170
        /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
171
        template< class SinglePassRange1, class SinglePassRange2 >
172
        inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
173
0
        {
174
0
            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
175
0
            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
176
177
0
            return ::boost::range_detail::equal(
178
0
                ::boost::begin(rng1), ::boost::end(rng1),
179
0
                ::boost::begin(rng2), ::boost::end(rng2) );
180
0
        }
181
182
        /// \overload
183
        template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
184
        inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
185
                           BinaryPredicate pred )
186
        {
187
            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
188
            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
189
190
            return ::boost::range_detail::equal(
191
                ::boost::begin(rng1), ::boost::end(rng1),
192
                ::boost::begin(rng2), ::boost::end(rng2),
193
                pred);
194
        }
195
196
    } // namespace range
197
    using ::boost::range::equal;
198
} // namespace boost
199
200
#endif // include guard
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/as_literal.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Range library
2
//
3
//  Copyright Thorsten Ottosen 2006. Use, modification and
4
//  distribution is subject to the Boost Software License, Version
5
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
11
#ifndef BOOST_RANGE_AS_LITERAL_HPP
12
#define BOOST_RANGE_AS_LITERAL_HPP
13
14
#if defined(_MSC_VER)
15
# pragma once
16
#endif
17
18
#include <boost/range/iterator_range.hpp>
19
#include <boost/range/detail/str_types.hpp>
20
21
#include <boost/detail/workaround.hpp>
22
23
#include <cstring>
24
25
#if !defined(BOOST_NO_CXX11_CHAR16_T) || !defined(BOOST_NO_CXX11_CHAR32_T)
26
#include <string>  // for std::char_traits
27
#endif
28
29
#ifndef BOOST_NO_CWCHAR
30
#include <cwchar>
31
#endif
32
33
namespace boost
34
{
35
    namespace range_detail
36
    {
37
        inline std::size_t length( const char* s )
38
33
        {
39
33
            return strlen( s );
40
33
        }
41
42
#ifndef BOOST_NO_CXX11_CHAR16_T
43
        inline std::size_t length( const char16_t* s )
44
0
        {
45
0
            return std::char_traits<char16_t>::length( s );
46
0
        }
47
#endif
48
49
#ifndef BOOST_NO_CXX11_CHAR32_T
50
        inline std::size_t length( const char32_t* s )
51
0
        {
52
0
            return std::char_traits<char32_t>::length( s );
53
0
        }
54
#endif
55
56
#ifndef BOOST_NO_CWCHAR
57
        inline std::size_t length( const wchar_t* s )
58
0
        {
59
0
            return wcslen( s );
60
0
        }
61
#endif
62
63
        //
64
        // Remark: the compiler cannot choose between T* and T[sz]
65
        // overloads, so we must put the T* internal to the
66
        // unconstrained version.
67
        //
68
69
        inline bool is_char_ptr( char* )
70
0
        {
71
0
            return true;
72
0
        }
73
74
        inline bool is_char_ptr( const char* )
75
33
        {
76
33
            return true;
77
33
        }
78
79
#ifndef BOOST_NO_CXX11_CHAR16_T
80
        inline bool is_char_ptr( char16_t* )
81
0
        {
82
0
            return true;
83
0
        }
84
85
        inline bool is_char_ptr( const char16_t* )
86
0
        {
87
0
            return true;
88
0
        }
89
#endif
90
91
#ifndef BOOST_NO_CXX11_CHAR32_T
92
        inline bool is_char_ptr( char32_t* )
93
0
        {
94
0
            return true;
95
0
        }
96
97
        inline bool is_char_ptr( const char32_t* )
98
0
        {
99
0
            return true;
100
0
        }
101
#endif
102
103
#ifndef BOOST_NO_CWCHAR
104
        inline bool is_char_ptr( wchar_t* )
105
0
        {
106
0
            return true;
107
0
        }
108
109
        inline bool is_char_ptr( const wchar_t* )
110
0
        {
111
0
            return true;
112
0
        }
113
#endif
114
115
        template< class T >
116
        inline long is_char_ptr( const T& /* r */ )
117
21
        {
118
21
            return 0L;
119
21
        }
120
121
        template< class T >
122
        inline iterator_range<T*>
123
        make_range( T* const r, bool )
124
33
        {
125
33
            return iterator_range<T*>( r, r + length(r) );
126
33
        }
127
128
        template< class T >
129
        inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<T>::type>
130
        make_range( T& r, long )
131
21
        {
132
21
            return boost::make_iterator_range( r );
133
21
        }
134
135
    }
136
137
    template< class Range >
138
    inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type>
139
    as_literal( Range& r )
140
    {
141
        return range_detail::make_range( r, range_detail::is_char_ptr(r) );
142
    }
143
144
    template< class Range >
145
    inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type>
146
    as_literal( const Range& r )
147
21
    {
148
21
        return range_detail::make_range( r, range_detail::is_char_ptr(r) );
149
21
    }
150
151
    template< class Char, std::size_t sz >
152
    inline iterator_range<Char*> as_literal( Char (&arr)[sz] )
153
    {
154
        return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
155
    }
156
157
    template< class Char, std::size_t sz >
158
    inline iterator_range<const Char*> as_literal( const Char (&arr)[sz] )
159
33
    {
160
33
        return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
161
33
    }
_ZN5boost10as_literalIcLm2EEENS_14iterator_rangeIPKT_EERAT0__S3_
Line
Count
Source
159
18
    {
160
18
        return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
161
18
    }
_ZN5boost10as_literalIcLm1EEENS_14iterator_rangeIPKT_EERAT0__S3_
Line
Count
Source
159
15
    {
160
15
        return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
161
15
    }
162
}
163
164
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/begin.hpp
Line
Count
Source
1
// Boost.Range library
2
//
3
//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
4
//  distribution is subject to the Boost Software License, Version
5
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
11
#ifndef BOOST_RANGE_BEGIN_HPP
12
#define BOOST_RANGE_BEGIN_HPP
13
14
#if defined(_MSC_VER)
15
# pragma once
16
#endif
17
18
#include <boost/range/config.hpp>
19
20
#include <boost/range/iterator.hpp>
21
#include <boost/config.hpp>
22
#include <boost/config/workaround.hpp>
23
24
namespace boost
25
{
26
27
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
28
namespace range_detail
29
{
30
#endif
31
32
    //////////////////////////////////////////////////////////////////////
33
    // primary template
34
    //////////////////////////////////////////////////////////////////////
35
36
    template< typename C >
37
    BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
38
    range_begin( C& c )
39
261
    {
40
        //
41
        // If you get a compile-error here, it is most likely because
42
        // you have not implemented range_begin() properly in
43
        // the namespace of C
44
        //
45
261
        return c.begin();
46
261
    }
_ZN5boost12range_detail11range_beginIKNS_14iterator_rangeIPKcEEEENS_14range_iteratorIT_vE4typeERS8_
Line
Count
Source
39
90
    {
40
        //
41
        // If you get a compile-error here, it is most likely because
42
        // you have not implemented range_begin() properly in
43
        // the namespace of C
44
        //
45
90
        return c.begin();
46
90
    }
_ZN5boost12range_detail11range_beginIKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_14range_iteratorIT_vE4typeERSB_
Line
Count
Source
39
21
    {
40
        //
41
        // If you get a compile-error here, it is most likely because
42
        // you have not implemented range_begin() properly in
43
        // the namespace of C
44
        //
45
21
        return c.begin();
46
21
    }
_ZN5boost12range_detail11range_beginINS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEENS_14range_iteratorIT_vE4typeERSA_
Line
Count
Source
39
21
    {
40
        //
41
        // If you get a compile-error here, it is most likely because
42
        // you have not implemented range_begin() properly in
43
        // the namespace of C
44
        //
45
21
        return c.begin();
46
21
    }
_ZN5boost12range_detail11range_beginIKNS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEENS_14range_iteratorIT_vE4typeERSB_
Line
Count
Source
39
54
    {
40
        //
41
        // If you get a compile-error here, it is most likely because
42
        // you have not implemented range_begin() properly in
43
        // the namespace of C
44
        //
45
54
        return c.begin();
46
54
    }
_ZN5boost12range_detail11range_beginINS_14iterator_rangeINSt3__111__wrap_iterIPcEEEEEENS_14range_iteratorIT_vE4typeERS9_
Line
Count
Source
39
30
    {
40
        //
41
        // If you get a compile-error here, it is most likely because
42
        // you have not implemented range_begin() properly in
43
        // the namespace of C
44
        //
45
30
        return c.begin();
46
30
    }
_ZN5boost12range_detail11range_beginINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_14range_iteratorIT_vE4typeERSA_
Line
Count
Source
39
45
    {
40
        //
41
        // If you get a compile-error here, it is most likely because
42
        // you have not implemented range_begin() properly in
43
        // the namespace of C
44
        //
45
45
        return c.begin();
46
45
    }
47
48
    //////////////////////////////////////////////////////////////////////
49
    // pair
50
    //////////////////////////////////////////////////////////////////////
51
52
    template< typename Iterator >
53
    BOOST_CONSTEXPR inline Iterator range_begin( const std::pair<Iterator,Iterator>& p )
54
    {
55
        return p.first;
56
    }
57
58
    template< typename Iterator >
59
    BOOST_CONSTEXPR inline Iterator range_begin( std::pair<Iterator,Iterator>& p )
60
    {
61
        return p.first;
62
    }
63
64
    //////////////////////////////////////////////////////////////////////
65
    // array
66
    //////////////////////////////////////////////////////////////////////
67
68
    //
69
    // May this be discarded? Or is it needed for bad compilers?
70
    //
71
    template< typename T, std::size_t sz >
72
    BOOST_CONSTEXPR inline const T* range_begin( const T (&a)[sz] ) BOOST_NOEXCEPT
73
    {
74
        return a;
75
    }
76
77
    template< typename T, std::size_t sz >
78
    BOOST_CONSTEXPR inline T* range_begin( T (&a)[sz] ) BOOST_NOEXCEPT
79
    {
80
        return a;
81
    }
82
83
84
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
85
} // namespace 'range_detail'
86
#endif
87
88
// Use a ADL namespace barrier to avoid ambiguity with other unqualified
89
// calls. This is particularly important with C++0x encouraging
90
// unqualified calls to begin/end.
91
namespace range_adl_barrier
92
{
93
94
template< class T >
95
#if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
96
BOOST_CONSTEXPR
97
#endif
98
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
99
96
{
100
96
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
101
96
    using namespace range_detail;
102
96
#endif
103
96
    return range_begin( r );
104
96
}
_ZN5boost17range_adl_barrier5beginINS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEENS_14range_iteratorIT_vE4typeERSA_
Line
Count
Source
99
21
{
100
21
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
101
21
    using namespace range_detail;
102
21
#endif
103
21
    return range_begin( r );
104
21
}
_ZN5boost17range_adl_barrier5beginINS_14iterator_rangeINSt3__111__wrap_iterIPcEEEEEENS_14range_iteratorIT_vE4typeERS9_
Line
Count
Source
99
30
{
100
30
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
101
30
    using namespace range_detail;
102
30
#endif
103
30
    return range_begin( r );
104
30
}
_ZN5boost17range_adl_barrier5beginINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_14range_iteratorIT_vE4typeERSA_
Line
Count
Source
99
45
{
100
45
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
101
45
    using namespace range_detail;
102
45
#endif
103
45
    return range_begin( r );
104
45
}
105
106
template< class T >
107
#if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
108
BOOST_CONSTEXPR
109
#endif
110
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
111
165
{
112
165
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
113
165
    using namespace range_detail;
114
165
#endif
115
165
    return range_begin( r );
116
165
}
_ZN5boost17range_adl_barrier5beginINS_14iterator_rangeIPKcEEEENS_14range_iteratorIKT_vE4typeERS8_
Line
Count
Source
111
90
{
112
90
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
113
90
    using namespace range_detail;
114
90
#endif
115
90
    return range_begin( r );
116
90
}
_ZN5boost17range_adl_barrier5beginINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_14range_iteratorIKT_vE4typeERSB_
Line
Count
Source
111
21
{
112
21
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
113
21
    using namespace range_detail;
114
21
#endif
115
21
    return range_begin( r );
116
21
}
_ZN5boost17range_adl_barrier5beginINS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEENS_14range_iteratorIKT_vE4typeERSB_
Line
Count
Source
111
54
{
112
54
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
113
54
    using namespace range_detail;
114
54
#endif
115
54
    return range_begin( r );
116
54
}
117
118
    } // namespace range_adl_barrier
119
} // namespace boost
120
121
namespace boost
122
{
123
    namespace range_adl_barrier
124
    {
125
        template< class T >
126
        inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
127
        const_begin( const T& r )
128
        {
129
            return boost::range_adl_barrier::begin( r );
130
        }
131
    } // namespace range_adl_barrier
132
133
    using namespace range_adl_barrier;
134
} // namespace boost
135
136
#endif
137
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/concepts.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Range library concept checks
2
//
3
//  Copyright Neil Groves 2009. Use, modification and distribution
4
//  are subject to the Boost Software License, Version 1.0. (See
5
//  accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
//  Copyright Daniel Walker 2006. Use, modification and distribution
9
//  are subject to the Boost Software License, Version 1.0. (See
10
//  accompanying file LICENSE_1_0.txt or copy at
11
//  http://www.boost.org/LICENSE_1_0.txt)
12
//
13
// For more information, see http://www.boost.org/libs/range/
14
//
15
16
#ifndef BOOST_RANGE_CONCEPTS_HPP
17
#define BOOST_RANGE_CONCEPTS_HPP
18
19
#include <boost/concept_check.hpp>
20
#include <boost/iterator/iterator_concepts.hpp>
21
#include <boost/range/begin.hpp>
22
#include <boost/range/end.hpp>
23
#include <boost/range/iterator.hpp>
24
#include <boost/range/value_type.hpp>
25
#include <boost/range/detail/misc_concept.hpp>
26
#include <boost/type_traits/remove_reference.hpp>
27
28
#include <iterator>
29
30
/*!
31
 * \file
32
 * \brief Concept checks for the Boost Range library.
33
 *
34
 * The structures in this file may be used in conjunction with the
35
 * Boost Concept Check library to insure that the type of a function
36
 * parameter is compatible with a range concept. If not, a meaningful
37
 * compile time error is generated. Checks are provided for the range
38
 * concepts related to iterator traversal categories. For example, the
39
 * following line checks that the type T models the ForwardRange
40
 * concept.
41
 *
42
 * \code
43
 * BOOST_CONCEPT_ASSERT((ForwardRangeConcept<T>));
44
 * \endcode
45
 *
46
 * A different concept check is required to ensure writeable value
47
 * access. For example to check for a ForwardRange that can be written
48
 * to, the following code is required.
49
 *
50
 * \code
51
 * BOOST_CONCEPT_ASSERT((WriteableForwardRangeConcept<T>));
52
 * \endcode
53
 *
54
 * \see http://www.boost.org/libs/range/doc/range.html for details
55
 * about range concepts.
56
 * \see http://www.boost.org/libs/iterator/doc/iterator_concepts.html
57
 * for details about iterator concepts.
58
 * \see http://www.boost.org/libs/concept_check/concept_check.htm for
59
 * details about concept checks.
60
 */
61
62
namespace boost {
63
64
    namespace range_detail {
65
66
#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
67
68
// List broken compiler versions here:
69
#ifndef __clang__
70
    #ifdef __GNUC__
71
        // GNUC 4.2 has strange issues correctly detecting compliance with the Concepts
72
        // hence the least disruptive approach is to turn-off the concept checking for
73
        // this version of the compiler.
74
        #if __GNUC__ == 4 && __GNUC_MINOR__ == 2
75
            #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
76
        #endif
77
    #endif
78
79
    #ifdef __GCCXML__
80
        // GCC XML, unsurprisingly, has the same issues
81
        #if __GCCXML_GNUC__ == 4 && __GCCXML_GNUC_MINOR__ == 2
82
            #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
83
        #endif
84
    #endif
85
#endif
86
87
    #ifdef BOOST_BORLANDC
88
        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
89
    #endif
90
91
    #ifdef __PATHCC__
92
        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
93
    #endif
94
95
// Default to using the concept asserts unless we have defined it off
96
// during the search for black listed compilers.
97
    #ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
98
        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 1
99
    #endif
100
101
#endif
102
103
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
104
0
    #define BOOST_RANGE_CONCEPT_ASSERT( x ) BOOST_CONCEPT_ASSERT( x )
105
#else
106
    #define BOOST_RANGE_CONCEPT_ASSERT( x )
107
#endif
108
109
        // Rationale for the inclusion of redefined iterator concept
110
        // classes:
111
        //
112
        // The Range algorithms often do not require that the iterators are
113
        // Assignable or default constructable, but the correct standard
114
        // conformant iterators do require the iterators to be a model of the
115
        // Assignable concept.
116
        // Iterators that contains a functor that is not assignable therefore
117
        // are not correct models of the standard iterator concepts,
118
        // despite being adequate for most algorithms. An example of this
119
        // use case is the combination of the boost::adaptors::filtered
120
        // class with a boost::lambda::bind generated functor.
121
        // Ultimately modeling the range concepts using composition
122
        // with the Boost.Iterator concepts would render the library
123
        // incompatible with many common Boost.Lambda expressions.
124
        template<class Iterator>
125
        struct IncrementableIteratorConcept : CopyConstructible<Iterator>
126
        {
127
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
128
            typedef BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator>::type traversal_category;
129
130
            BOOST_RANGE_CONCEPT_ASSERT((
131
                Convertible<
132
                    traversal_category,
133
                    incrementable_traversal_tag
134
                >));
135
136
            BOOST_CONCEPT_USAGE(IncrementableIteratorConcept)
137
            {
138
                ++i;
139
                (void)i++;
140
            }
141
        private:
142
            Iterator i;
143
#endif
144
        };
145
146
        template<class Iterator>
147
        struct SinglePassIteratorConcept
148
            : IncrementableIteratorConcept<Iterator>
149
            , EqualityComparable<Iterator>
150
        {
151
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
152
            BOOST_RANGE_CONCEPT_ASSERT((
153
                Convertible<
154
                    BOOST_DEDUCED_TYPENAME SinglePassIteratorConcept::traversal_category,
155
                    single_pass_traversal_tag
156
                >));
157
158
            BOOST_CONCEPT_USAGE(SinglePassIteratorConcept)
159
            {
160
                Iterator i2(++i);
161
                boost::ignore_unused_variable_warning(i2);
162
163
                // deliberately we are loose with the postfix version for the single pass
164
                // iterator due to the commonly poor adherence to the specification means that
165
                // many algorithms would be unusable, whereas actually without the check they
166
                // work
167
                (void)(i++);
168
169
                BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::reference r1(*i);
170
                boost::ignore_unused_variable_warning(r1);
171
172
                BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::reference r2(*(++i));
173
                boost::ignore_unused_variable_warning(r2);
174
            }
175
        private:
176
            Iterator i;
177
#endif
178
        };
179
180
        template<class Iterator>
181
        struct ForwardIteratorConcept
182
            : SinglePassIteratorConcept<Iterator>
183
            , DefaultConstructible<Iterator>
184
        {
185
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
186
            typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::difference_type difference_type;
187
188
            BOOST_MPL_ASSERT((is_integral<difference_type>));
189
            BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
190
191
            BOOST_RANGE_CONCEPT_ASSERT((
192
                Convertible<
193
                    BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
194
                    forward_traversal_tag
195
                >));
196
197
            BOOST_CONCEPT_USAGE(ForwardIteratorConcept)
198
            {
199
                // See the above note in the SinglePassIteratorConcept about the handling of the
200
                // postfix increment. Since with forward and better iterators there is no need
201
                // for a proxy, we can sensibly require that the dereference result
202
                // is convertible to reference.
203
                Iterator i2(i++);
204
                boost::ignore_unused_variable_warning(i2);
205
                BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::reference r(*(i++));
206
                boost::ignore_unused_variable_warning(r);
207
            }
208
        private:
209
            Iterator i;
210
#endif
211
         };
212
213
         template<class Iterator>
214
         struct BidirectionalIteratorConcept
215
             : ForwardIteratorConcept<Iterator>
216
         {
217
 #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
218
             BOOST_RANGE_CONCEPT_ASSERT((
219
                 Convertible<
220
                     BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::traversal_category,
221
                     bidirectional_traversal_tag
222
                 >));
223
224
             BOOST_CONCEPT_USAGE(BidirectionalIteratorConcept)
225
             {
226
                 --i;
227
                 (void)i--;
228
             }
229
         private:
230
             Iterator i;
231
 #endif
232
         };
233
234
         template<class Iterator>
235
         struct RandomAccessIteratorConcept
236
             : BidirectionalIteratorConcept<Iterator>
237
         {
238
 #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
239
             BOOST_RANGE_CONCEPT_ASSERT((
240
                 Convertible<
241
                     BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::traversal_category,
242
                     random_access_traversal_tag
243
                 >));
244
245
             BOOST_CONCEPT_USAGE(RandomAccessIteratorConcept)
246
             {
247
                 i += n;
248
                 i = i + n;
249
                 i = n + i;
250
                 i -= n;
251
                 i = i - n;
252
                 n = i - j;
253
             }
254
         private:
255
             BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept<Iterator>::difference_type n;
256
             Iterator i;
257
             Iterator j;
258
 #endif
259
         };
260
261
    } // namespace range_detail
262
263
    //! Check if a type T models the SinglePassRange range concept.
264
    template<class T>
265
    struct SinglePassRangeConcept
266
    {
267
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
268
        // A few compilers don't like the rvalue reference T types so just
269
        // remove it.
270
        typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type Rng;
271
272
        typedef BOOST_DEDUCED_TYPENAME range_iterator<
273
            Rng const
274
        >::type const_iterator;
275
276
        typedef BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type iterator;
277
278
        BOOST_RANGE_CONCEPT_ASSERT((
279
                range_detail::SinglePassIteratorConcept<iterator>));
280
281
        BOOST_RANGE_CONCEPT_ASSERT((
282
                range_detail::SinglePassIteratorConcept<const_iterator>));
283
284
        BOOST_CONCEPT_USAGE(SinglePassRangeConcept)
285
        {
286
            // This has been modified from assigning to this->i
287
            // (where i was a member variable) to improve
288
            // compatibility with Boost.Lambda
289
            iterator i1 = boost::begin(*m_range);
290
            iterator i2 = boost::end(*m_range);
291
292
            boost::ignore_unused_variable_warning(i1);
293
            boost::ignore_unused_variable_warning(i2);
294
295
            const_constraints(*m_range);
296
        }
297
298
    private:
299
        void const_constraints(const Rng& const_range)
300
0
        {
301
0
            const_iterator ci1 = boost::begin(const_range);
302
0
            const_iterator ci2 = boost::end(const_range);
303
0
304
0
            boost::ignore_unused_variable_warning(ci1);
305
0
            boost::ignore_unused_variable_warning(ci2);
306
0
        }
307
308
       // Rationale:
309
       // The type of m_range is T* rather than T because it allows
310
       // T to be an abstract class. The other obvious alternative of
311
       // T& produces a warning on some compilers.
312
       Rng* m_range;
313
#endif
314
    };
315
316
    //! Check if a type T models the ForwardRange range concept.
317
    template<class T>
318
    struct ForwardRangeConcept : SinglePassRangeConcept<T>
319
    {
320
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
321
        BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::iterator>));
322
        BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::const_iterator>));
323
#endif
324
    };
325
326
    template<class T>
327
    struct WriteableRangeConcept
328
    {
329
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
330
        typedef BOOST_DEDUCED_TYPENAME range_iterator<T>::type iterator;
331
332
        BOOST_CONCEPT_USAGE(WriteableRangeConcept)
333
        {
334
            *i = v;
335
        }
336
    private:
337
        iterator i;
338
        BOOST_DEDUCED_TYPENAME range_value<T>::type v;
339
#endif
340
    };
341
342
    //! Check if a type T models the WriteableForwardRange range concept.
343
    template<class T>
344
    struct WriteableForwardRangeConcept
345
        : ForwardRangeConcept<T>
346
        , WriteableRangeConcept<T>
347
    {
348
    };
349
350
    //! Check if a type T models the BidirectionalRange range concept.
351
    template<class T>
352
    struct BidirectionalRangeConcept : ForwardRangeConcept<T>
353
    {
354
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
355
        BOOST_RANGE_CONCEPT_ASSERT((range_detail::BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::iterator>));
356
        BOOST_RANGE_CONCEPT_ASSERT((range_detail::BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::const_iterator>));
357
#endif
358
    };
359
360
    //! Check if a type T models the WriteableBidirectionalRange range concept.
361
    template<class T>
362
    struct WriteableBidirectionalRangeConcept
363
        : BidirectionalRangeConcept<T>
364
        , WriteableRangeConcept<T>
365
    {
366
    };
367
368
    //! Check if a type T models the RandomAccessRange range concept.
369
    template<class T>
370
    struct RandomAccessRangeConcept : BidirectionalRangeConcept<T>
371
    {
372
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
373
        BOOST_RANGE_CONCEPT_ASSERT((range_detail::RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::iterator>));
374
        BOOST_RANGE_CONCEPT_ASSERT((range_detail::RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::const_iterator>));
375
#endif
376
    };
377
378
    //! Check if a type T models the WriteableRandomAccessRange range concept.
379
    template<class T>
380
    struct WriteableRandomAccessRangeConcept
381
        : RandomAccessRangeConcept<T>
382
        , WriteableRangeConcept<T>
383
    {
384
    };
385
386
} // namespace boost
387
388
#endif // BOOST_RANGE_CONCEPTS_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/detail/implementation_help.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Range library
2
//
3
//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
4
//  distribution is subject to the Boost Software License, Version
5
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
11
#ifndef BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
12
#define BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
13
14
#include <boost/range/config.hpp>
15
#include <boost/range/detail/common.hpp>
16
#include <boost/type_traits/is_same.hpp>
17
#include <cstddef>
18
#include <string.h>
19
20
#ifndef BOOST_NO_CWCHAR
21
#include <wchar.h>
22
#endif
23
24
namespace boost
25
{
26
    namespace range_detail
27
    {
28
        template <typename T>
29
        inline void boost_range_silence_warning( const T& ) { }
30
31
        /////////////////////////////////////////////////////////////////////
32
        // end() help
33
        /////////////////////////////////////////////////////////////////////
34
35
        inline const char* str_end( const char* s, const char* )
36
0
        {
37
0
            return s + strlen( s );
38
0
        }
39
40
#ifndef BOOST_NO_CWCHAR
41
        inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
42
0
        {
43
0
            return s + wcslen( s );
44
0
        }
45
#else
46
        inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
47
        {
48
            if( s == 0 || s[0] == 0 )
49
                return s;
50
            while( *++s != 0 )
51
                ;
52
            return s;
53
        }
54
#endif
55
56
        template< class Char >
57
        inline Char* str_end( Char* s )
58
        {
59
            return const_cast<Char*>( str_end( s, s ) );
60
        }
61
62
        template< class T, std::size_t sz >
63
        BOOST_CONSTEXPR inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] ) BOOST_NOEXCEPT
64
        {
65
            return boost_range_array + sz;
66
        }
67
68
        template< class T, std::size_t sz >
69
        BOOST_CONSTEXPR inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] ) BOOST_NOEXCEPT
70
        {
71
            return boost_range_array + sz;
72
        }
73
74
        /////////////////////////////////////////////////////////////////////
75
        // size() help
76
        /////////////////////////////////////////////////////////////////////
77
78
        template< class Char >
79
        inline std::size_t str_size( const Char* const& s )
80
        {
81
            return str_end( s ) - s;
82
        }
83
84
        template< class T, std::size_t sz >
85
        inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz] )
86
        {
87
            boost_range_silence_warning( boost_range_array );
88
            return sz;
89
        }
90
91
        template< class T, std::size_t sz >
92
        inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz] )
93
        {
94
            boost_range_silence_warning( boost_range_array );
95
            return sz;
96
        }
97
98
        inline bool is_same_address(const void* l, const void* r)
99
0
        {
100
0
            return l == r;
101
0
        }
102
103
        template<class T1, class T2>
104
        inline bool is_same_object(const T1& l, const T2& r)
105
        {
106
            return range_detail::is_same_address(&l, &r);
107
        }
108
109
    } // namespace 'range_detail'
110
111
} // namespace 'boost'
112
113
114
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/detail/safe_bool.hpp
Line
Count
Source
1
//  This header intentionally has no include guards.
2
//
3
//  Copyright (c) 2010 Neil Groves
4
//  Distributed under the Boost Software License, Version 1.0.
5
//  See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt
7
//
8
// This code utilises the experience gained during the evolution of
9
// <boost/smart_ptr/operator_bool.hpp>
10
#ifndef BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
11
#define BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
12
13
#include <boost/config.hpp>
14
#include <boost/range/config.hpp>
15
16
namespace boost
17
{
18
    namespace range_detail
19
    {
20
21
template<class DataMemberPtr>
22
class safe_bool
23
{
24
public:
25
    typedef safe_bool this_type;
26
27
#if (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570)) || defined(__CINT_)
28
    typedef bool unspecified_bool_type;
29
    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
30
    {
31
        return x;
32
    }
33
#elif defined(_MANAGED)
34
    static void unspecified_bool(this_type***)
35
    {
36
    }
37
    typedef void(*unspecified_bool_type)(this_type***);
38
    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
39
    {
40
        return x ? unspecified_bool : 0;
41
    }
42
#elif \
43
    ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
44
    ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
45
    ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
46
47
    typedef bool (this_type::*unspecified_bool_type)() const;
48
49
    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
50
    {
51
        return x ? &this_type::detail_safe_bool_member_fn : 0;
52
    }
53
private:
54
    bool detail_safe_bool_member_fn() const { return false; }
55
#else
56
    typedef DataMemberPtr unspecified_bool_type;
57
    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr p)
58
30
    {
59
30
        return x ? p : 0;
60
30
    }
61
#endif
62
private:
63
    safe_bool();
64
    safe_bool(const safe_bool&);
65
    void operator=(const safe_bool&);
66
    ~safe_bool();
67
};
68
69
    } // namespace range_detail
70
} // namespace boost
71
72
#endif // include guard
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/distance.hpp
Line
Count
Source
1
// Boost.Range library
2
//
3
//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
4
//  distribution is subject to the Boost Software License, Version
5
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
11
#ifndef BOOST_RANGE_DISTANCE_HPP
12
#define BOOST_RANGE_DISTANCE_HPP
13
14
#if defined(_MSC_VER)
15
# pragma once
16
#endif
17
18
#include <boost/iterator/distance.hpp>
19
#include <boost/range/begin.hpp>
20
#include <boost/range/end.hpp>
21
#include <boost/range/difference_type.hpp>
22
23
namespace boost
24
{
25
26
    namespace range_distance_adl_barrier
27
    {
28
        template< class T >
29
        inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME range_difference<T>::type
30
        distance( const T& r )
31
3
        {
32
3
            return boost::iterators::distance( boost::begin( r ), boost::end( r ) );
33
3
        }
34
    }
35
36
    using namespace range_distance_adl_barrier;
37
38
} // namespace 'boost'
39
40
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/empty.hpp
Line
Count
Source
1
// Boost.Range library
2
//
3
//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
4
//  distribution is subject to the Boost Software License, Version
5
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
11
#ifndef BOOST_RANGE_EMPTY_HPP
12
#define BOOST_RANGE_EMPTY_HPP
13
14
#if defined(_MSC_VER)
15
# pragma once
16
#endif
17
18
#include <boost/range/config.hpp>
19
#include <boost/range/begin.hpp>
20
#include <boost/range/end.hpp>
21
22
namespace boost 
23
{ 
24
25
    template< class T >
26
    inline bool empty( const T& r )
27
39
    {
28
39
        return boost::begin( r ) == boost::end( r );
29
39
    }
30
31
} // namespace 'boost'
32
33
34
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/end.hpp
Line
Count
Source
1
// Boost.Range library
2
//
3
//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
4
//  distribution is subject to the Boost Software License, Version
5
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
11
#ifndef BOOST_RANGE_END_HPP
12
#define BOOST_RANGE_END_HPP
13
14
#if defined(_MSC_VER)
15
# pragma once
16
#endif
17
18
#include <boost/range/config.hpp>
19
20
#include <boost/range/detail/implementation_help.hpp>
21
#include <boost/range/iterator.hpp>
22
#include <boost/range/const_iterator.hpp>
23
#include <boost/config.hpp>
24
#include <boost/config/workaround.hpp>
25
26
namespace boost
27
{
28
29
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
30
namespace range_detail
31
{
32
#endif
33
34
        //////////////////////////////////////////////////////////////////////
35
        // primary template
36
        //////////////////////////////////////////////////////////////////////
37
        template< typename C >
38
        BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
39
        range_end( C& c )
40
276
        {
41
            //
42
            // If you get a compile-error here, it is most likely because
43
            // you have not implemented range_begin() properly in
44
            // the namespace of C
45
            //
46
276
            return c.end();
47
276
        }
_ZN5boost12range_detail9range_endIKNS_14iterator_rangeIPKcEEEENS_14range_iteratorIT_vE4typeERS8_
Line
Count
Source
40
90
        {
41
            //
42
            // If you get a compile-error here, it is most likely because
43
            // you have not implemented range_begin() properly in
44
            // the namespace of C
45
            //
46
90
            return c.end();
47
90
        }
_ZN5boost12range_detail9range_endIKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_14range_iteratorIT_vE4typeERSB_
Line
Count
Source
40
21
        {
41
            //
42
            // If you get a compile-error here, it is most likely because
43
            // you have not implemented range_begin() properly in
44
            // the namespace of C
45
            //
46
21
            return c.end();
47
21
        }
_ZN5boost12range_detail9range_endINS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEENS_14range_iteratorIT_vE4typeERSA_
Line
Count
Source
40
21
        {
41
            //
42
            // If you get a compile-error here, it is most likely because
43
            // you have not implemented range_begin() properly in
44
            // the namespace of C
45
            //
46
21
            return c.end();
47
21
        }
_ZN5boost12range_detail9range_endIKNS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEENS_14range_iteratorIT_vE4typeERSB_
Line
Count
Source
40
54
        {
41
            //
42
            // If you get a compile-error here, it is most likely because
43
            // you have not implemented range_begin() properly in
44
            // the namespace of C
45
            //
46
54
            return c.end();
47
54
        }
_ZN5boost12range_detail9range_endINS_14iterator_rangeINSt3__111__wrap_iterIPcEEEEEENS_14range_iteratorIT_vE4typeERS9_
Line
Count
Source
40
30
        {
41
            //
42
            // If you get a compile-error here, it is most likely because
43
            // you have not implemented range_begin() properly in
44
            // the namespace of C
45
            //
46
30
            return c.end();
47
30
        }
_ZN5boost12range_detail9range_endINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_14range_iteratorIT_vE4typeERSA_
Line
Count
Source
40
60
        {
41
            //
42
            // If you get a compile-error here, it is most likely because
43
            // you have not implemented range_begin() properly in
44
            // the namespace of C
45
            //
46
60
            return c.end();
47
60
        }
48
49
        //////////////////////////////////////////////////////////////////////
50
        // pair
51
        //////////////////////////////////////////////////////////////////////
52
53
        template< typename Iterator >
54
        BOOST_CONSTEXPR inline Iterator range_end( const std::pair<Iterator,Iterator>& p )
55
        {
56
            return p.second;
57
        }
58
59
        template< typename Iterator >
60
        BOOST_CONSTEXPR inline Iterator range_end( std::pair<Iterator,Iterator>& p )
61
        {
62
            return p.second;
63
        }
64
65
        //////////////////////////////////////////////////////////////////////
66
        // array
67
        //////////////////////////////////////////////////////////////////////
68
69
        template< typename T, std::size_t sz >
70
        BOOST_CONSTEXPR inline const T* range_end( const T (&a)[sz] ) BOOST_NOEXCEPT
71
        {
72
            return range_detail::array_end<T,sz>( a );
73
        }
74
75
        template< typename T, std::size_t sz >
76
        BOOST_CONSTEXPR inline T* range_end( T (&a)[sz] ) BOOST_NOEXCEPT
77
        {
78
            return range_detail::array_end<T,sz>( a );
79
        }
80
81
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
82
} // namespace 'range_detail'
83
#endif
84
85
namespace range_adl_barrier
86
{
87
88
template< class T >
89
#if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
90
BOOST_CONSTEXPR
91
#endif
92
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
93
111
{
94
111
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
95
111
    using namespace range_detail;
96
111
#endif
97
111
    return range_end( r );
98
111
}
_ZN5boost17range_adl_barrier3endINS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEENS_14range_iteratorIT_vE4typeERSA_
Line
Count
Source
93
21
{
94
21
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
95
21
    using namespace range_detail;
96
21
#endif
97
21
    return range_end( r );
98
21
}
_ZN5boost17range_adl_barrier3endINS_14iterator_rangeINSt3__111__wrap_iterIPcEEEEEENS_14range_iteratorIT_vE4typeERS9_
Line
Count
Source
93
30
{
94
30
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
95
30
    using namespace range_detail;
96
30
#endif
97
30
    return range_end( r );
98
30
}
_ZN5boost17range_adl_barrier3endINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_14range_iteratorIT_vE4typeERSA_
Line
Count
Source
93
60
{
94
60
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
95
60
    using namespace range_detail;
96
60
#endif
97
60
    return range_end( r );
98
60
}
99
100
template< class T >
101
#if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
102
BOOST_CONSTEXPR
103
#endif
104
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r )
105
165
{
106
165
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
107
165
    using namespace range_detail;
108
165
#endif
109
165
    return range_end( r );
110
165
}
_ZN5boost17range_adl_barrier3endINS_14iterator_rangeIPKcEEEENS_14range_iteratorIKT_vE4typeERS8_
Line
Count
Source
105
90
{
106
90
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
107
90
    using namespace range_detail;
108
90
#endif
109
90
    return range_end( r );
110
90
}
_ZN5boost17range_adl_barrier3endINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_14range_iteratorIKT_vE4typeERSB_
Line
Count
Source
105
21
{
106
21
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
107
21
    using namespace range_detail;
108
21
#endif
109
21
    return range_end( r );
110
21
}
_ZN5boost17range_adl_barrier3endINS_14iterator_rangeINSt3__111__wrap_iterIPKcEEEEEENS_14range_iteratorIKT_vE4typeERSB_
Line
Count
Source
105
54
{
106
54
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
107
54
    using namespace range_detail;
108
54
#endif
109
54
    return range_end( r );
110
54
}
111
112
    } // namespace range_adl_barrier
113
} // namespace 'boost'
114
115
namespace boost
116
{
117
    namespace range_adl_barrier
118
    {
119
        template< class T >
120
        BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
121
        const_end( const T& r )
122
        {
123
            return boost::range_adl_barrier::end( r );
124
        }
125
    } // namespace range_adl_barrier
126
    using namespace range_adl_barrier;
127
} // namespace boost
128
129
#endif
130
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/range/iterator_range_core.hpp
Line
Count
Source (jump to first uncovered line)
1
// Boost.Range library
2
//
3
//  Copyright Neil Groves & Thorsten Ottosen & Pavol Droba 2003-2004.
4
//  Use, modification and distribution is subject to the Boost Software
5
//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6
//  http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// For more information, see http://www.boost.org/libs/range/
9
//
10
// Credits:
11
// 'michel' reported Trac 9072 which included a patch for allowing references
12
// to function types.
13
//
14
#ifndef BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
15
#define BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
16
17
#include <boost/config.hpp> // Define __STL_CONFIG_H, if appropriate.
18
#include <boost/detail/workaround.hpp>
19
20
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
21
    #pragma warning( push )
22
    #pragma warning( disable : 4996 )
23
#endif
24
25
#include <boost/assert.hpp>
26
#include <boost/iterator/iterator_traits.hpp>
27
#include <boost/iterator/iterator_facade.hpp>
28
#include <boost/mpl/if.hpp>
29
#include <boost/mpl/not.hpp>
30
#include <boost/mpl/or.hpp>
31
#include <boost/type_traits/is_abstract.hpp>
32
#include <boost/type_traits/is_array.hpp>
33
#include <boost/type_traits/is_base_and_derived.hpp>
34
#include <boost/type_traits/is_convertible.hpp>
35
#include <boost/type_traits/is_function.hpp>
36
#include <boost/type_traits/is_pointer.hpp>
37
#include <boost/type_traits/is_same.hpp>
38
#include <boost/range/functions.hpp>
39
#include <boost/range/iterator.hpp>
40
#include <boost/range/difference_type.hpp>
41
#include <boost/range/has_range_iterator.hpp>
42
#include <boost/range/algorithm/equal.hpp>
43
#include <boost/range/detail/safe_bool.hpp>
44
#include <boost/utility/enable_if.hpp>
45
#include <boost/next_prior.hpp>
46
#include <iterator>
47
#include <algorithm>
48
#include <cstddef>
49
50
/*! \file
51
    Defines the \c iterator_class and related functions.
52
    \c iterator_range is a simple wrapper of iterator pair idiom. It provides
53
    a rich subset of Container interface.
54
*/
55
56
57
namespace boost
58
{
59
    namespace iterator_range_detail
60
    {
61
        //
62
        // The functions adl_begin and adl_end are implemented in a separate
63
        // class for gcc-2.9x
64
        //
65
        template<class IteratorT>
66
        struct iterator_range_impl {
67
            template< class ForwardRange >
68
            static IteratorT adl_begin( ForwardRange& r )
69
51
            {
70
51
                return IteratorT( boost::begin( r ) );
71
51
            }
_ZN5boost21iterator_range_detail19iterator_range_implINSt3__111__wrap_iterIPKcEEE9adl_beginIKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEES6_RT_
Line
Count
Source
69
21
            {
70
21
                return IteratorT( boost::begin( r ) );
71
21
            }
_ZN5boost21iterator_range_detail19iterator_range_implINSt3__111__wrap_iterIPKcEEE9adl_beginINS_14iterator_rangeINS3_IPcEEEEEES6_RT_
Line
Count
Source
69
15
            {
70
15
                return IteratorT( boost::begin( r ) );
71
15
            }
_ZN5boost21iterator_range_detail19iterator_range_implINSt3__111__wrap_iterIPcEEE9adl_beginINS_14iterator_rangeIS5_EEEES5_RT_
Line
Count
Source
69
15
            {
70
15
                return IteratorT( boost::begin( r ) );
71
15
            }
72
73
            template< class ForwardRange >
74
            static IteratorT adl_end( ForwardRange& r )
75
51
            {
76
51
                return IteratorT( boost::end( r ) );
77
51
            }
_ZN5boost21iterator_range_detail19iterator_range_implINSt3__111__wrap_iterIPKcEEE7adl_endIKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEES6_RT_
Line
Count
Source
75
21
            {
76
21
                return IteratorT( boost::end( r ) );
77
21
            }
_ZN5boost21iterator_range_detail19iterator_range_implINSt3__111__wrap_iterIPKcEEE7adl_endINS_14iterator_rangeINS3_IPcEEEEEES6_RT_
Line
Count
Source
75
15
            {
76
15
                return IteratorT( boost::end( r ) );
77
15
            }
_ZN5boost21iterator_range_detail19iterator_range_implINSt3__111__wrap_iterIPcEEE7adl_endINS_14iterator_rangeIS5_EEEES5_RT_
Line
Count
Source
75
15
            {
76
15
                return IteratorT( boost::end( r ) );
77
15
            }
78
        };
79
80
        template< class Left, class Right >
81
        inline bool less_than( const Left& l, const Right& r )
82
        {
83
            return std::lexicographical_compare( boost::begin(l),
84
                                                 boost::end(l),
85
                                                 boost::begin(r),
86
                                                 boost::end(r) );
87
        }
88
        
89
        template< class Left, class Right >
90
        inline bool greater_than( const Left& l, const Right& r )
91
        {
92
            return iterator_range_detail::less_than(r,l);
93
        }
94
        
95
        template< class Left, class Right >
96
        inline bool less_or_equal_than( const Left& l, const Right& r )
97
        {
98
            return !iterator_range_detail::less_than(r,l);
99
        }
100
        
101
        template< class Left, class Right >
102
        inline bool greater_or_equal_than( const Left& l, const Right& r )
103
        {
104
            return !iterator_range_detail::less_than(l,r);
105
        }
106
107
        // This version is maintained since it is used in other boost libraries
108
        // such as Boost.Assign
109
        template< class Left, class Right >
110
        inline bool equal(const Left& l, const Right& r)
111
        {
112
            return boost::equal(l, r);
113
        }
114
115
struct range_tag
116
{
117
};
118
119
struct const_range_tag
120
{
121
};
122
123
struct iterator_range_tag
124
{
125
};
126
127
typedef char (&incrementable_t)[1];
128
typedef char (&bidirectional_t)[2];
129
typedef char (&random_access_t)[3];
130
131
incrementable_t test_traversal_tag(boost::incrementable_traversal_tag);
132
bidirectional_t test_traversal_tag(boost::bidirectional_traversal_tag);
133
random_access_t test_traversal_tag(boost::random_access_traversal_tag);
134
135
template<std::size_t S>
136
struct pure_iterator_traversal_impl
137
{
138
    typedef boost::incrementable_traversal_tag type;
139
};
140
141
template<>
142
struct pure_iterator_traversal_impl<sizeof(bidirectional_t)>
143
{
144
    typedef boost::bidirectional_traversal_tag type;
145
};
146
147
template<>
148
struct pure_iterator_traversal_impl<sizeof(random_access_t)>
149
{
150
    typedef boost::random_access_traversal_tag type;
151
};
152
153
template<typename IteratorT>
154
struct pure_iterator_traversal
155
{
156
    typedef
157
        BOOST_DEDUCED_TYPENAME iterator_traversal<IteratorT>::type
158
    traversal_t;
159
    BOOST_STATIC_CONSTANT(
160
        std::size_t,
161
        traversal_i = sizeof(iterator_range_detail::test_traversal_tag((traversal_t())))
162
    );
163
    typedef
164
        BOOST_DEDUCED_TYPENAME pure_iterator_traversal_impl<traversal_i>::type
165
    type;
166
};
167
168
template<class IteratorT, class TraversalTag>
169
class iterator_range_base
170
    : public iterator_range_tag
171
{
172
    typedef range_detail::safe_bool<
173
                IteratorT iterator_range_base<IteratorT, TraversalTag>::*
174
    > safe_bool_t;
175
176
    typedef iterator_range_base<IteratorT, TraversalTag> type;
177
178
protected:
179
    typedef iterator_range_impl<IteratorT> impl;
180
181
public:
182
    typedef BOOST_DEDUCED_TYPENAME
183
        safe_bool_t::unspecified_bool_type unspecified_bool_type;
184
185
    typedef BOOST_DEDUCED_TYPENAME
186
        iterator_value<IteratorT>::type value_type;
187
188
    typedef BOOST_DEDUCED_TYPENAME
189
        iterator_difference<IteratorT>::type difference_type;
190
191
    typedef std::size_t size_type; // note: must be unsigned
192
193
    // Needed because value-type is the same for
194
    // const and non-const iterators
195
    typedef BOOST_DEDUCED_TYPENAME
196
                iterator_reference<IteratorT>::type reference;
197
198
    //! const_iterator type
199
    /*!
200
        There is no distinction between const_iterator and iterator.
201
        These typedefs are provides to fulfill container interface
202
    */
203
    typedef IteratorT const_iterator;
204
    //! iterator type
205
    typedef IteratorT iterator;
206
207
protected:
208
    iterator_range_base()
209
        : m_Begin()
210
        , m_End()
211
6
    {
212
6
    }
213
214
    template<class Iterator>
215
    iterator_range_base(Iterator Begin, Iterator End)
216
        : m_Begin(Begin)
217
        , m_End(End)
218
270
    {
219
270
    }
_ZN5boost21iterator_range_detail19iterator_range_baseIPKcNS_9iterators27incrementable_traversal_tagEEC2IS3_EET_S8_
Line
Count
Source
218
63
    {
219
63
    }
_ZN5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPKcEENS_9iterators27incrementable_traversal_tagEEC2IS6_EET_SB_
Line
Count
Source
218
162
    {
219
162
    }
_ZN5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPcEENS_9iterators27incrementable_traversal_tagEEC2IS5_EET_SA_
Line
Count
Source
218
45
    {
219
45
    }
220
221
public:
222
    IteratorT begin() const
223
384
    {
224
384
        return m_Begin;
225
384
    }
_ZNK5boost21iterator_range_detail19iterator_range_baseIPKcNS_9iterators27incrementable_traversal_tagEE5beginEv
Line
Count
Source
223
129
    {
224
129
        return m_Begin;
225
129
    }
_ZNK5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPKcEENS_9iterators27incrementable_traversal_tagEE5beginEv
Line
Count
Source
223
195
    {
224
195
        return m_Begin;
225
195
    }
_ZNK5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPcEENS_9iterators27incrementable_traversal_tagEE5beginEv
Line
Count
Source
223
60
    {
224
60
        return m_Begin;
225
60
    }
226
227
    IteratorT end() const
228
387
    {
229
387
        return m_End;
230
387
    }
_ZNK5boost21iterator_range_detail19iterator_range_baseIPKcNS_9iterators27incrementable_traversal_tagEE3endEv
Line
Count
Source
228
168
    {
229
168
        return m_End;
230
168
    }
_ZNK5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPKcEENS_9iterators27incrementable_traversal_tagEE3endEv
Line
Count
Source
228
159
    {
229
159
        return m_End;
230
159
    }
_ZNK5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPcEENS_9iterators27incrementable_traversal_tagEE3endEv
Line
Count
Source
228
60
    {
229
60
        return m_End;
230
60
    }
231
232
    bool empty() const
233
30
    {
234
30
        return m_Begin == m_End;
235
30
    }
_ZNK5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPKcEENS_9iterators27incrementable_traversal_tagEE5emptyEv
Line
Count
Source
233
15
    {
234
15
        return m_Begin == m_End;
235
15
    }
_ZNK5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPcEENS_9iterators27incrementable_traversal_tagEE5emptyEv
Line
Count
Source
233
15
    {
234
15
        return m_Begin == m_End;
235
15
    }
236
237
    operator unspecified_bool_type() const
238
30
    {
239
30
        return safe_bool_t::to_unspecified_bool(
240
30
                    m_Begin != m_End, &iterator_range_base::m_Begin);
241
30
    }
242
243
    bool operator!() const
244
    {
245
        return empty();
246
    }
247
248
    bool equal(const iterator_range_base& r) const
249
    {
250
        return m_Begin == r.m_Begin && m_End == r.m_End;
251
    }
252
253
   reference front() const
254
   {
255
       BOOST_ASSERT(!empty());
256
       return *m_Begin;
257
   }
258
259
   void drop_front()
260
   {
261
       BOOST_ASSERT(!empty());
262
       ++m_Begin;
263
   }
264
265
   void drop_front(difference_type n)
266
   {
267
       BOOST_ASSERT(n >= difference_type());
268
       std::advance(this->m_Begin, n);
269
   }
270
   
271
   // Deprecated
272
   void pop_front() { drop_front(); }
273
274
protected:
275
    template<class Iterator>
276
    void assign(Iterator first, Iterator last)
277
15
    {
278
15
        m_Begin = first;
279
15
        m_End = last;
280
15
    }
281
282
    template<class SinglePassRange>
283
    void assign(const SinglePassRange& r)
284
    {
285
        m_Begin = impl::adl_begin(r);
286
        m_End = impl::adl_end(r);
287
    }
288
289
    template<class SinglePassRange>
290
    void assign(SinglePassRange& r)
291
    {
292
        m_Begin = impl::adl_begin(r);
293
        m_End = impl::adl_end(r);
294
    }
295
296
    IteratorT m_Begin;
297
    IteratorT m_End;
298
};
299
300
template<class IteratorT>
301
class iterator_range_base<IteratorT, bidirectional_traversal_tag>
302
        : public iterator_range_base<IteratorT, incrementable_traversal_tag>
303
{
304
    typedef iterator_range_base<IteratorT, incrementable_traversal_tag> base_type;
305
306
protected:
307
    iterator_range_base()
308
6
    {
309
6
    }
310
311
    template<class Iterator>
312
    iterator_range_base(Iterator first, Iterator last)
313
        : base_type(first, last)
314
270
    {
315
270
    }
_ZN5boost21iterator_range_detail19iterator_range_baseIPKcNS_9iterators27bidirectional_traversal_tagEEC2IS3_EET_S8_
Line
Count
Source
314
63
    {
315
63
    }
_ZN5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPKcEENS_9iterators27bidirectional_traversal_tagEEC2IS6_EET_SB_
Line
Count
Source
314
162
    {
315
162
    }
_ZN5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPcEENS_9iterators27bidirectional_traversal_tagEEC2IS5_EET_SA_
Line
Count
Source
314
45
    {
315
45
    }
316
317
public:
318
    typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type;
319
    typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
320
321
    reference back() const
322
    {
323
        BOOST_ASSERT(!this->empty());
324
        return *boost::prior(this->m_End);
325
    }
326
327
    void drop_back()
328
    {
329
        BOOST_ASSERT(!this->empty());
330
        --this->m_End;
331
    }
332
333
    void drop_back(difference_type n)
334
    {
335
        BOOST_ASSERT(n >= difference_type());
336
        std::advance(this->m_End, -n);
337
    }
338
    
339
    // Deprecated
340
    void pop_back() { drop_back(); }
341
};
342
343
template<class IteratorT>
344
class iterator_range_base<IteratorT, random_access_traversal_tag>
345
        : public iterator_range_base<IteratorT, bidirectional_traversal_tag>
346
{
347
    typedef iterator_range_base<
348
                IteratorT, bidirectional_traversal_tag> base_type;
349
350
public:
351
    typedef BOOST_DEDUCED_TYPENAME
352
        boost::mpl::if_<
353
            boost::mpl::or_<
354
                boost::is_abstract<
355
                    BOOST_DEDUCED_TYPENAME base_type::value_type
356
                >,
357
                boost::is_array<
358
                    BOOST_DEDUCED_TYPENAME base_type::value_type
359
                >,
360
                boost::is_function<
361
                    BOOST_DEDUCED_TYPENAME base_type::value_type
362
                >
363
            >,
364
            BOOST_DEDUCED_TYPENAME base_type::reference,
365
            BOOST_DEDUCED_TYPENAME base_type::value_type
366
        >::type abstract_value_type;
367
368
    // Rationale:
369
    // typedef these here to reduce verbiage in the implementation of this
370
    // type.
371
    typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type;
372
    typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type;
373
    typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
374
375
protected:
376
    iterator_range_base()
377
6
    {
378
6
    }
379
380
    template<class Iterator>
381
    iterator_range_base(Iterator first, Iterator last)
382
        : base_type(first, last)
383
270
    {
384
270
    }
_ZN5boost21iterator_range_detail19iterator_range_baseIPKcNS_9iterators27random_access_traversal_tagEEC2IS3_EET_S8_
Line
Count
Source
383
63
    {
384
63
    }
_ZN5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPKcEENS_9iterators27random_access_traversal_tagEEC2IS6_EET_SB_
Line
Count
Source
383
162
    {
384
162
    }
_ZN5boost21iterator_range_detail19iterator_range_baseINSt3__111__wrap_iterIPcEENS_9iterators27random_access_traversal_tagEEC2IS5_EET_SA_
Line
Count
Source
383
45
    {
384
45
    }
385
386
public:
387
    reference operator[](difference_type at) const
388
    {
389
        BOOST_ASSERT(at >= 0);
390
        BOOST_ASSERT(static_cast<typename base_type::size_type>(at) < size());
391
        return this->m_Begin[at];
392
    }
393
394
    //
395
    // When storing transform iterators, operator[]()
396
    // fails because it returns by reference. Therefore
397
    // operator()() is provided for these cases.
398
    //
399
    abstract_value_type operator()(difference_type at) const
400
    {
401
        BOOST_ASSERT(at >= 0);
402
        BOOST_ASSERT(static_cast<typename base_type::size_type>(at) < size());
403
        return this->m_Begin[at];
404
    }
405
406
    BOOST_DEDUCED_TYPENAME base_type::size_type size() const
407
    {
408
        return this->m_End - this->m_Begin;
409
    }
410
};
411
412
    }
413
414
//  iterator range template class -----------------------------------------//
415
416
        //! iterator_range class
417
        /*!
418
            An \c iterator_range delimits a range in a sequence by beginning and ending iterators.
419
            An iterator_range can be passed to an algorithm which requires a sequence as an input.
420
            For example, the \c toupper() function may be used most frequently on strings,
421
            but can also be used on iterator_ranges:
422
423
            \code
424
                boost::tolower( find( s, "UPPERCASE STRING" ) );
425
            \endcode
426
427
            Many algorithms working with sequences take a pair of iterators,
428
            delimiting a working range, as an arguments. The \c iterator_range class is an
429
            encapsulation of a range identified by a pair of iterators.
430
            It provides a collection interface,
431
            so it is possible to pass an instance to an algorithm requiring a collection as an input.
432
        */
433
        template<class IteratorT>
434
        class iterator_range
435
            : public iterator_range_detail::iterator_range_base<
436
                    IteratorT,
437
                    BOOST_DEDUCED_TYPENAME iterator_range_detail::pure_iterator_traversal<IteratorT>::type
438
                >
439
        {
440
            typedef iterator_range_detail::iterator_range_base<
441
                    IteratorT,
442
                    BOOST_DEDUCED_TYPENAME iterator_range_detail::pure_iterator_traversal<IteratorT>::type
443
            > base_type;
444
445
            template<class Source>
446
            struct is_compatible_range_
447
              : is_convertible<
448
                    BOOST_DEDUCED_TYPENAME mpl::eval_if<
449
                        has_range_iterator<Source>,
450
                        range_iterator<Source>,
451
                        mpl::identity<void>
452
                    >::type,
453
                    BOOST_DEDUCED_TYPENAME base_type::iterator
454
                >
455
            {
456
            };
457
458
            template<class Source>
459
            struct is_compatible_range
460
                : mpl::and_<
461
                    mpl::not_<
462
                        is_convertible<
463
                            Source,
464
                            BOOST_DEDUCED_TYPENAME base_type::iterator
465
                        >
466
                    >,
467
                    is_compatible_range_<Source>
468
                >
469
            {
470
            };
471
472
        protected:
473
            typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
474
475
        public:
476
            typedef iterator_range<IteratorT> type;
477
478
            iterator_range()
479
6
            {
480
6
            }
481
482
            template<class Iterator>
483
            iterator_range(Iterator first, Iterator last)
484
                : base_type(first, last)
485
219
            {
486
219
            }
_ZN5boost14iterator_rangeIPKcEC2IS2_EET_S5_
Line
Count
Source
485
63
            {
486
63
            }
_ZN5boost14iterator_rangeINSt3__111__wrap_iterIPKcEEEC2IS5_EET_S8_
Line
Count
Source
485
126
            {
486
126
            }
_ZN5boost14iterator_rangeINSt3__111__wrap_iterIPcEEEC2IS4_EET_S7_
Line
Count
Source
485
30
            {
486
30
            }
487
488
            template<class SinglePassRange>
489
            iterator_range(
490
                const SinglePassRange& r,
491
                BOOST_DEDUCED_TYPENAME ::boost::enable_if<
492
                    is_compatible_range<const SinglePassRange>
493
                >::type* = 0
494
            )
495
                : base_type(impl::adl_begin(r), impl::adl_end(r))
496
            {
497
            }
498
499
            template<class SinglePassRange>
500
            iterator_range(
501
                SinglePassRange& r,
502
                BOOST_DEDUCED_TYPENAME ::boost::enable_if<
503
                    is_compatible_range<SinglePassRange>
504
                >::type* = 0
505
            )
506
                : base_type(impl::adl_begin(r), impl::adl_end(r))
507
30
            {
508
30
            }
_ZN5boost14iterator_rangeINSt3__111__wrap_iterIPKcEEEC2INS0_INS2_IPcEEEEEERT_PNS_9enable_ifINS6_19is_compatible_rangeISB_EEvE4typeE
Line
Count
Source
507
15
            {
508
15
            }
_ZN5boost14iterator_rangeINSt3__111__wrap_iterIPcEEEC2IS5_EERT_PNS_9enable_ifINS5_19is_compatible_rangeIS7_EEvE4typeE
Line
Count
Source
507
15
            {
508
15
            }
509
510
            template<class SinglePassRange>
511
            iterator_range(const SinglePassRange& r,
512
                           iterator_range_detail::const_range_tag)
513
                : base_type(impl::adl_begin(r), impl::adl_end(r))
514
21
            {
515
21
            }
516
517
            template<class SinglePassRange>
518
            iterator_range(SinglePassRange& r,
519
                           iterator_range_detail::range_tag)
520
                : base_type(impl::adl_begin(r), impl::adl_end(r))
521
            {
522
            }
523
524
            template<class Iterator>
525
            iterator_range& operator=(const iterator_range<Iterator>& other)
526
            {
527
                this->assign(other.begin(), other.end());
528
                return *this;
529
            }
530
531
            template<class Iterator>
532
            iterator_range& operator=(iterator_range<Iterator>& other)
533
15
            {
534
15
                this->assign(other.begin(), other.end());
535
15
                return *this;
536
15
            }
537
538
            template<class SinglePassRange>
539
            iterator_range& operator=(SinglePassRange& r)
540
            {
541
                this->assign(r);
542
                return *this;
543
            }
544
545
            template<class SinglePassRange>
546
            iterator_range& operator=(const SinglePassRange& r)
547
            {
548
                this->assign(r);
549
                return *this;
550
            }
551
552
            iterator_range& advance_begin(
553
                BOOST_DEDUCED_TYPENAME base_type::difference_type n)
554
            {
555
                std::advance(this->m_Begin, n);
556
                return *this;
557
            }
558
559
            iterator_range& advance_end(
560
                BOOST_DEDUCED_TYPENAME base_type::difference_type n)
561
            {
562
                std::advance(this->m_End, n);
563
                return *this;
564
            }
565
566
        protected:
567
            //
568
            // Allow subclasses an easy way to access the
569
            // base type
570
            //
571
            typedef iterator_range iterator_range_;
572
        };
573
574
//  iterator range free-standing operators ---------------------------//
575
576
        /////////////////////////////////////////////////////////////////////
577
        // comparison operators
578
        /////////////////////////////////////////////////////////////////////
579
580
        template< class IteratorT, class ForwardRange >
581
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
582
            mpl::not_<is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
583
            bool
584
        >::type
585
        operator==( const ForwardRange& l, const iterator_range<IteratorT>& r )
586
        {
587
            return boost::equal( l, r );
588
        }
589
590
        template< class IteratorT, class ForwardRange >
591
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
592
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
593
            bool
594
        >::type
595
        operator!=( const ForwardRange& l, const iterator_range<IteratorT>& r )
596
        {
597
            return !boost::equal( l, r );
598
        }
599
600
        template< class IteratorT, class ForwardRange >
601
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
602
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
603
            bool
604
        >::type
605
        operator<( const ForwardRange& l, const iterator_range<IteratorT>& r )
606
        {
607
            return iterator_range_detail::less_than( l, r );
608
        }
609
        
610
        template< class IteratorT, class ForwardRange >
611
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
612
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
613
            bool
614
        >::type
615
        operator<=( const ForwardRange& l, const iterator_range<IteratorT>& r )
616
        {
617
            return iterator_range_detail::less_or_equal_than( l, r );
618
        }
619
        
620
        template< class IteratorT, class ForwardRange >
621
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
622
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
623
            bool
624
        >::type
625
        operator>( const ForwardRange& l, const iterator_range<IteratorT>& r )
626
        {
627
            return iterator_range_detail::greater_than( l, r );
628
        }
629
        
630
        template< class IteratorT, class ForwardRange >
631
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
632
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
633
            bool
634
        >::type
635
        operator>=( const ForwardRange& l, const iterator_range<IteratorT>& r )
636
        {
637
            return iterator_range_detail::greater_or_equal_than( l, r );
638
        }
639
640
        template< class Iterator1T, class Iterator2T >
641
        inline bool
642
        operator==( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
643
0
        {
644
0
            return boost::equal( l, r );
645
0
        }
646
647
        template< class IteratorT, class ForwardRange >
648
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
649
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
650
            bool
651
        >::type
652
        operator==( const iterator_range<IteratorT>& l, const ForwardRange& r )
653
        {
654
            return boost::equal( l, r );
655
        }
656
657
658
        template< class Iterator1T, class Iterator2T >
659
        inline bool
660
        operator!=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
661
        {
662
            return !boost::equal( l, r );
663
        }
664
665
        template< class IteratorT, class ForwardRange >
666
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
667
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
668
            bool
669
        >::type
670
        operator!=( const iterator_range<IteratorT>& l, const ForwardRange& r )
671
        {
672
            return !boost::equal( l, r );
673
        }
674
675
676
        template< class Iterator1T, class Iterator2T >
677
        inline bool
678
        operator<( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
679
        {
680
            return iterator_range_detail::less_than( l, r );
681
        }
682
683
        template< class IteratorT, class ForwardRange >
684
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
685
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
686
            bool
687
        >::type
688
        operator<( const iterator_range<IteratorT>& l, const ForwardRange& r )
689
        {
690
            return iterator_range_detail::less_than( l, r );
691
        }
692
        
693
        template< class Iterator1T, class Iterator2T >
694
        inline bool
695
        operator<=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
696
        {
697
            return iterator_range_detail::less_or_equal_than( l, r );
698
        }
699
        
700
        template< class IteratorT, class ForwardRange >
701
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
702
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
703
            bool
704
        >::type
705
        operator<=( const iterator_range<IteratorT>& l, const ForwardRange& r )
706
        {
707
            return iterator_range_detail::less_or_equal_than( l, r );
708
        }
709
        
710
        template< class Iterator1T, class Iterator2T >
711
        inline bool
712
        operator>( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
713
        {
714
            return iterator_range_detail::greater_than( l, r );
715
        }
716
        
717
        template< class IteratorT, class ForwardRange >
718
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
719
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
720
            bool
721
        >::type
722
        operator>( const iterator_range<IteratorT>& l, const ForwardRange& r )
723
        {
724
            return iterator_range_detail::greater_than( l, r );
725
        }
726
        
727
        template< class Iterator1T, class Iterator2T >
728
        inline bool
729
        operator>=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
730
        {
731
            return iterator_range_detail::greater_or_equal_than( l, r );
732
        }
733
        
734
        template< class IteratorT, class ForwardRange >
735
        inline BOOST_DEDUCED_TYPENAME boost::enable_if<
736
            mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
737
            bool
738
        >::type
739
        operator>=( const iterator_range<IteratorT>& l, const ForwardRange& r )
740
        {
741
            return iterator_range_detail::greater_or_equal_than( l, r );
742
        }
743
744
//  iterator range utilities -----------------------------------------//
745
746
        //! iterator_range construct helper
747
        /*!
748
            Construct an \c iterator_range from a pair of iterators
749
750
            \param Begin A begin iterator
751
            \param End An end iterator
752
            \return iterator_range object
753
        */
754
        template< typename IteratorT >
755
        inline iterator_range< IteratorT >
756
        make_iterator_range( IteratorT Begin, IteratorT End )
757
        {
758
            return iterator_range<IteratorT>( Begin, End );
759
        }
760
761
        template<typename IteratorT, typename IntegerT>
762
        inline iterator_range<IteratorT>
763
        make_iterator_range_n(IteratorT first, IntegerT n)
764
        {
765
            return iterator_range<IteratorT>(first, boost::next(first, n));
766
        }
767
768
        //! iterator_range construct helper
769
        /*!
770
            Construct an \c iterator_range from a \c Range containing the begin
771
            and end iterators.
772
        */
773
        template< class ForwardRange >
774
        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
775
        make_iterator_range( ForwardRange& r )
776
        {
777
           return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
778
                ( r, iterator_range_detail::range_tag() );
779
        }
780
781
        template< class ForwardRange >
782
        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
783
        make_iterator_range( const ForwardRange& r )
784
21
        {
785
21
           return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
786
21
                ( r, iterator_range_detail::const_range_tag() );
787
21
        }
788
789
        namespace iterator_range_detail
790
        {
791
            template< class Range >
792
            inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
793
            make_range_impl( Range& r,
794
                             BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
795
                             BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
796
            {
797
                //
798
                // Not worth the effort
799
                //
800
                //if( advance_begin == 0 && advance_end == 0 )
801
                //    return make_iterator_range( r );
802
                //
803
804
                BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
805
                    new_begin = boost::begin( r ),
806
                    new_end   = boost::end( r );
807
                std::advance( new_begin, advance_begin );
808
                std::advance( new_end, advance_end );
809
                return make_iterator_range( new_begin, new_end );
810
            }
811
        }
812
813
        template< class Range >
814
        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
815
        make_iterator_range( Range& r,
816
                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
817
                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
818
        {
819
            return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
820
        }
821
822
        template< class Range >
823
        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type >
824
        make_iterator_range( const Range& r,
825
                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
826
                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
827
        {
828
            return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
829
        }
830
831
        //! copy a range into a sequence
832
        /*!
833
            Construct a new sequence of the specified type from the elements
834
            in the given range
835
836
            \param Range An input range
837
            \return New sequence
838
        */
839
        template< typename SeqT, typename Range >
840
        inline SeqT copy_range( const Range& r )
841
54
        {
842
54
            return SeqT( boost::begin( r ), boost::end( r ) );
843
54
        }
844
845
} // namespace 'boost'
846
847
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
848
    #pragma warning( pop )
849
#endif
850
851
#endif
852
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/config.hpp
Line
Count
Source
1
/*
2
 *
3
 * Copyright (c) 1998-2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the
7
 * Boost Software License, Version 1.0. (See accompanying file
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         config.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: regex extended config setup.
17
  */
18
19
#ifndef BOOST_REGEX_CONFIG_HPP
20
#define BOOST_REGEX_CONFIG_HPP
21
22
#if !((__cplusplus >= 201103L) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(BOOST_REGEX_CXX03))
23
#  define BOOST_REGEX_CXX03
24
#endif
25
26
#if defined(BOOST_REGEX_RECURSIVE) && !defined(BOOST_REGEX_CXX03)
27
#  define BOOST_REGEX_CXX03
28
#endif
29
30
#if defined(__has_include)
31
#if !defined(BOOST_REGEX_STANDALONE) && !__has_include(<boost/version.hpp>)
32
#define BOOST_REGEX_STANDALONE
33
#endif
34
#endif
35
36
/*
37
 * Borland C++ Fix/error check
38
 * this has to go *before* we include any std lib headers:
39
 */
40
#if defined(__BORLANDC__) && !defined(__clang__)
41
#  include <boost/regex/config/borland.hpp>
42
#endif
43
#ifndef BOOST_REGEX_STANDALONE
44
#include <boost/version.hpp>
45
#endif
46
47
/*************************************************************************
48
*
49
* Asserts:
50
*
51
*************************************************************************/
52
53
#ifdef BOOST_REGEX_STANDALONE
54
#include <cassert>
55
#  define BOOST_REGEX_ASSERT(x) assert(x)
56
#else
57
#include <boost/assert.hpp>
58
177
#  define BOOST_REGEX_ASSERT(x) BOOST_ASSERT(x)
59
#endif
60
61
/*****************************************************************************
62
 *
63
 *  Include all the headers we need here:
64
 *
65
 ****************************************************************************/
66
67
#ifdef __cplusplus
68
69
#  ifndef BOOST_REGEX_USER_CONFIG
70
#     define BOOST_REGEX_USER_CONFIG <boost/regex/user.hpp>
71
#  endif
72
73
#  include BOOST_REGEX_USER_CONFIG
74
75
#ifndef BOOST_REGEX_STANDALONE
76
#  include <boost/config.hpp>
77
#  include <boost/predef.h>
78
#endif
79
80
#else
81
   /*
82
    * C build,
83
    * don't include <boost/config.hpp> because that may
84
    * do C++ specific things in future...
85
    */
86
#  include <stdlib.h>
87
#  include <stddef.h>
88
#  ifdef _MSC_VER
89
#     define BOOST_MSVC _MSC_VER
90
#  endif
91
#endif
92
93
94
/****************************************************************************
95
*
96
* Legacy support:
97
*
98
*******************************************************************************/
99
100
#if defined(BOOST_NO_STD_LOCALE) || defined(BOOST_NO_CXX11_HDR_MUTEX) || defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) \
101
   || defined(BOOST_NO_CXX11_HDR_ATOMIC) || defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_CXX11_SMART_PTR) \
102
   || defined(BOOST_NO_CXX11_STATIC_ASSERT) || defined(BOOST_NO_NOEXCEPT)
103
#ifndef BOOST_REGEX_CXX03
104
#  define BOOST_REGEX_CXX03
105
#endif
106
#endif
107
108
/*****************************************************************************
109
 *
110
 *  Boilerplate regex config options:
111
 *
112
 ****************************************************************************/
113
114
/* Obsolete macro, use BOOST_VERSION instead: */
115
#define BOOST_RE_VERSION 500
116
117
/* fix: */
118
#if defined(_UNICODE) && !defined(UNICODE)
119
#define UNICODE
120
#endif
121
122
56
#define BOOST_REGEX_JOIN(X, Y) BOOST_REGEX_DO_JOIN(X, Y)
123
56
#define BOOST_REGEX_DO_JOIN(X, Y) BOOST_REGEX_DO_JOIN2(X,Y)
124
56
#define BOOST_REGEX_DO_JOIN2(X, Y) X##Y
125
126
#ifdef BOOST_FALLTHROUGH
127
50
#  define BOOST_REGEX_FALLTHROUGH BOOST_FALLTHROUGH
128
#else
129
130
#if defined(__clang__) && (__cplusplus >= 201103L) && defined(__has_warning)
131
#  if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
132
#    define BOOST_REGEX_FALLTHROUGH [[clang::fallthrough]]
133
#  endif
134
#endif
135
#if !defined(BOOST_REGEX_FALLTHROUGH) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1800) && (__cplusplus >= 201703)
136
#  define BOOST_REGEX_FALLTHROUGH [[fallthrough]]
137
#endif
138
#if !defined(BOOST_REGEX_FALLTHROUGH) && defined(__GNUC__) && (__GNUC__ >= 7)
139
#  define BOOST_REGEX_FALLTHROUGH __attribute__((fallthrough))
140
#endif
141
142
#if !defined(BOOST_REGEX_FALLTHROUGH)
143
#  define BOOST_REGEX_FALLTHROUGH
144
#endif
145
#endif
146
147
#ifdef BOOST_NORETURN
148
#  define BOOST_REGEX_NORETURN BOOST_NORETURN
149
#else
150
#  define BOOST_REGEX_NORETURN
151
#endif
152
153
154
/*
155
* Define a macro for the namespace that details are placed in, this includes the Boost
156
* version number to avoid mismatched header and library versions:
157
*/
158
56
#define BOOST_REGEX_DETAIL_NS BOOST_REGEX_JOIN(re_detail_, BOOST_RE_VERSION)
159
160
/*
161
 * Fix for gcc prior to 3.4: std::ctype<wchar_t> doesn't allow
162
 * masks to be combined, for example:
163
 * std::use_facet<std::ctype<wchar_t> >.is(std::ctype_base::lower|std::ctype_base::upper, L'a');
164
 * returns *false*.
165
 */
166
#if defined(__GLIBCPP__) && defined(BOOST_REGEX_CXX03)
167
#  define BOOST_REGEX_BUGGY_CTYPE_FACET
168
#endif
169
170
/*
171
 * If there isn't good enough wide character support then there will
172
 * be no wide character regular expressions:
173
 */
174
#if (defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_CWCTYPE) || defined(BOOST_NO_STD_WSTRING))
175
#  if !defined(BOOST_NO_WREGEX)
176
#     define BOOST_NO_WREGEX
177
#  endif
178
#else
179
#  if defined(__sgi) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
180
      /* STLPort on IRIX is misconfigured: <cwctype> does not compile
181
       * as a temporary fix include <wctype.h> instead and prevent inclusion
182
       * of STLPort version of <cwctype> */
183
#     include <wctype.h>
184
#     define __STLPORT_CWCTYPE
185
#     define _STLP_CWCTYPE
186
#  endif
187
188
#if defined(__cplusplus) && defined(BOOST_REGEX_CXX03)
189
#  include <boost/regex/config/cwchar.hpp>
190
#endif
191
192
#endif
193
194
/*
195
 * If Win32 support has been disabled for boost in general, then
196
 * it is for regex in particular:
197
 */
198
#if defined(BOOST_DISABLE_WIN32) && !defined(BOOST_REGEX_NO_W32)
199
#  define BOOST_REGEX_NO_W32
200
#endif
201
202
/* disable our own file-iterators and mapfiles if we can't
203
 * support them: */
204
#if defined(_WIN32)
205
#  if defined(BOOST_REGEX_NO_W32) || BOOST_PLAT_WINDOWS_RUNTIME
206
#    define BOOST_REGEX_NO_FILEITER
207
#  endif
208
#else /* defined(_WIN32) */
209
#  if !defined(BOOST_HAS_DIRENT_H)
210
#    define BOOST_REGEX_NO_FILEITER
211
#  endif
212
#endif
213
214
/* backwards compatibitity: */
215
#if defined(BOOST_RE_NO_LIB)
216
#  define BOOST_REGEX_NO_LIB
217
#endif
218
219
#if defined(__GNUC__) && !defined(_MSC_VER) && (defined(_WIN32) || defined(__CYGWIN__))
220
/* gcc on win32 has problems if you include <windows.h>
221
   (sporadically generates bad code). */
222
#  define BOOST_REGEX_NO_W32
223
#endif
224
#if defined(__COMO__) && !defined(BOOST_REGEX_NO_W32) && !defined(_MSC_EXTENSIONS)
225
#  define BOOST_REGEX_NO_W32
226
#endif
227
228
#ifdef BOOST_REGEX_STANDALONE
229
#  if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__)
230
#     define BOOST_REGEX_MSVC _MSC_VER
231
#endif
232
#elif defined(BOOST_MSVC)
233
#  define BOOST_REGEX_MSVC BOOST_MSVC
234
#endif
235
236
237
/*****************************************************************************
238
 *
239
 *  Set up dll import/export options:
240
 *
241
 ****************************************************************************/
242
243
#if (defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_REGEX_STATIC_LINK) && defined(BOOST_SYMBOL_IMPORT)
244
#  if defined(BOOST_REGEX_SOURCE)
245
#     define BOOST_REGEX_BUILD_DLL
246
#     define BOOST_REGEX_DECL BOOST_SYMBOL_EXPORT
247
#  else
248
#     define BOOST_REGEX_DECL BOOST_SYMBOL_IMPORT
249
#  endif
250
#else
251
#  define BOOST_REGEX_DECL
252
#endif
253
254
#ifdef BOOST_REGEX_CXX03
255
#if !defined(BOOST_REGEX_NO_LIB) && !defined(BOOST_REGEX_SOURCE) && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus)
256
#  define BOOST_LIB_NAME boost_regex
257
#  if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
258
#     define BOOST_DYN_LINK
259
#  endif
260
#  ifdef BOOST_REGEX_DIAG
261
#     define BOOST_LIB_DIAGNOSTIC
262
#  endif
263
#  include <boost/config/auto_link.hpp>
264
#endif
265
#endif
266
267
/*****************************************************************************
268
 *
269
 *  Set up function call type:
270
 *
271
 ****************************************************************************/
272
273
#if defined(_MSC_VER) && defined(_MSC_EXTENSIONS)
274
#if defined(_DEBUG) || defined(__MSVC_RUNTIME_CHECKS) || defined(_MANAGED) || defined(BOOST_REGEX_NO_FASTCALL)
275
#  define BOOST_REGEX_CALL __cdecl
276
#else
277
#  define BOOST_REGEX_CALL __fastcall
278
#endif
279
#  define BOOST_REGEX_CCALL __cdecl
280
#endif
281
282
#if defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32)
283
#if defined(__clang__)
284
#  define BOOST_REGEX_CALL __cdecl
285
#  define BOOST_REGEX_CCALL __cdecl
286
#else
287
#  define BOOST_REGEX_CALL __fastcall
288
#  define BOOST_REGEX_CCALL __stdcall
289
#endif
290
#endif
291
292
#ifndef BOOST_REGEX_CALL
293
#  define BOOST_REGEX_CALL
294
#endif
295
#ifndef BOOST_REGEX_CCALL
296
#define BOOST_REGEX_CCALL
297
#endif
298
299
/*****************************************************************************
300
 *
301
 *  Set up localisation model:
302
 *
303
 ****************************************************************************/
304
305
/* backwards compatibility: */
306
#ifdef BOOST_RE_LOCALE_C
307
#  define BOOST_REGEX_USE_C_LOCALE
308
#endif
309
310
#ifdef BOOST_RE_LOCALE_CPP
311
#  define BOOST_REGEX_USE_CPP_LOCALE
312
#endif
313
314
#if defined(__CYGWIN__)
315
#  define BOOST_REGEX_USE_C_LOCALE
316
#endif
317
318
/* use C++ locale when targeting windows store */
319
#if BOOST_PLAT_WINDOWS_RUNTIME
320
#  define BOOST_REGEX_USE_CPP_LOCALE
321
#  define BOOST_REGEX_NO_WIN32_LOCALE
322
#endif
323
324
/* Win32 defaults to native Win32 locale: */
325
#if defined(_WIN32) && \
326
    !defined(BOOST_REGEX_USE_WIN32_LOCALE) && \
327
    !defined(BOOST_REGEX_USE_C_LOCALE) && \
328
    !defined(BOOST_REGEX_USE_CPP_LOCALE) && \
329
    !defined(BOOST_REGEX_NO_W32) && \
330
    !defined(BOOST_REGEX_NO_WIN32_LOCALE)
331
#  define BOOST_REGEX_USE_WIN32_LOCALE
332
#endif
333
/* otherwise use C++ locale if supported: */
334
#if !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE) && !defined(BOOST_NO_STD_LOCALE)
335
#  define BOOST_REGEX_USE_CPP_LOCALE
336
#endif
337
/* otherwise use C locale: */
338
#if !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE)
339
#  define BOOST_REGEX_USE_C_LOCALE
340
#endif
341
342
#ifndef BOOST_REGEX_MAX_STATE_COUNT
343
5
#  define BOOST_REGEX_MAX_STATE_COUNT 100000000
344
#endif
345
346
347
/*****************************************************************************
348
 *
349
 *  Error Handling for exception free compilers:
350
 *
351
 ****************************************************************************/
352
353
#ifdef BOOST_NO_EXCEPTIONS
354
/*
355
 * If there are no exceptions then we must report critical-errors
356
 * the only way we know how; by terminating.
357
 */
358
#include <stdexcept>
359
#include <string>
360
#include <boost/throw_exception.hpp>
361
362
#  define BOOST_REGEX_NOEH_ASSERT(x)\
363
if(0 == (x))\
364
{\
365
   std::string s("Error: critical regex++ failure in: ");\
366
   s.append(#x);\
367
   std::runtime_error e(s);\
368
   boost::throw_exception(e);\
369
}
370
#else
371
/*
372
 * With exceptions then error handling is taken care of and
373
 * there is no need for these checks:
374
 */
375
#  define BOOST_REGEX_NOEH_ASSERT(x)
376
#endif
377
378
379
/*****************************************************************************
380
 *
381
 *  Stack protection under MS Windows:
382
 *
383
 ****************************************************************************/
384
385
#if !defined(BOOST_REGEX_NO_W32) && !defined(BOOST_REGEX_V3)
386
#  if(defined(_WIN32) || defined(_WIN64) || defined(_WINCE)) \
387
        && !(defined(__GNUC__) || defined(__BORLANDC__) && defined(__clang__)) \
388
        && !(defined(__BORLANDC__) && (__BORLANDC__ >= 0x600)) \
389
        && !(defined(__MWERKS__) && (__MWERKS__ <= 0x3003))
390
#     define BOOST_REGEX_HAS_MS_STACK_GUARD
391
#  endif
392
#elif defined(BOOST_REGEX_HAS_MS_STACK_GUARD)
393
#  undef BOOST_REGEX_HAS_MS_STACK_GUARD
394
#endif
395
396
#if defined(__cplusplus) && defined(BOOST_REGEX_HAS_MS_STACK_GUARD)
397
398
namespace boost{
399
namespace BOOST_REGEX_DETAIL_NS{
400
401
BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page();
402
403
}
404
}
405
406
#endif
407
408
409
/*****************************************************************************
410
 *
411
 *  Algorithm selection and configuration.
412
 *  These options are now obsolete for C++11 and later (regex v5).
413
 *
414
 ****************************************************************************/
415
416
#if !defined(BOOST_REGEX_RECURSIVE) && !defined(BOOST_REGEX_NON_RECURSIVE)
417
#  if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && !defined(_STLP_DEBUG) && !defined(__STL_DEBUG) && !(defined(_MSC_VER) && (_MSC_VER >= 1400)) && defined(BOOST_REGEX_CXX03)
418
#     define BOOST_REGEX_RECURSIVE
419
#  else
420
#     define BOOST_REGEX_NON_RECURSIVE
421
#  endif
422
#endif
423
424
#ifdef BOOST_REGEX_NON_RECURSIVE
425
#  ifdef BOOST_REGEX_RECURSIVE
426
#     error "Can't set both BOOST_REGEX_RECURSIVE and BOOST_REGEX_NON_RECURSIVE"
427
#  endif
428
#  ifndef BOOST_REGEX_BLOCKSIZE
429
6
#     define BOOST_REGEX_BLOCKSIZE 4096
430
#  endif
431
#  if BOOST_REGEX_BLOCKSIZE < 512
432
#     error "BOOST_REGEX_BLOCKSIZE must be at least 512"
433
#  endif
434
#  ifndef BOOST_REGEX_MAX_BLOCKS
435
5
#     define BOOST_REGEX_MAX_BLOCKS 1024
436
#  endif
437
#  ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
438
#     undef BOOST_REGEX_HAS_MS_STACK_GUARD
439
#  endif
440
#  ifndef BOOST_REGEX_MAX_CACHE_BLOCKS
441
43
#     define BOOST_REGEX_MAX_CACHE_BLOCKS 16
442
#  endif
443
#endif
444
445
446
/*****************************************************************************
447
 *
448
 *  Diagnostics:
449
 *
450
 ****************************************************************************/
451
452
#ifdef BOOST_REGEX_CONFIG_INFO
453
BOOST_REGEX_DECL void BOOST_REGEX_CALL print_regex_library_info();
454
#endif
455
456
#if defined(BOOST_REGEX_DIAG)
457
#  pragma message ("BOOST_REGEX_DECL" BOOST_STRINGIZE(=BOOST_REGEX_DECL))
458
#  pragma message ("BOOST_REGEX_CALL" BOOST_STRINGIZE(=BOOST_REGEX_CALL))
459
#  pragma message ("BOOST_REGEX_CCALL" BOOST_STRINGIZE(=BOOST_REGEX_CCALL))
460
#ifdef BOOST_REGEX_USE_C_LOCALE
461
#  pragma message ("Using C locale in regex traits class")
462
#elif BOOST_REGEX_USE_CPP_LOCALE
463
#  pragma message ("Using C++ locale in regex traits class")
464
#else
465
#  pragma message ("Using Win32 locale in regex traits class")
466
#endif
467
#if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
468
#  pragma message ("Dynamic linking enabled")
469
#endif
470
#if defined(BOOST_REGEX_NO_LIB) || defined(BOOST_ALL_NO_LIB)
471
#  pragma message ("Auto-linking disabled")
472
#endif
473
#ifdef BOOST_REGEX_NO_EXTERNAL_TEMPLATES
474
#  pragma message ("Extern templates disabled")
475
#endif
476
477
#endif
478
479
#endif
480
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/basic_regex.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 1998-2004 John Maddock
4
 * Copyright 2011 Garmin Ltd. or its subsidiaries
5
 *
6
 * Distributed under the Boost Software License, Version 1.0.
7
 * (See accompanying file LICENSE_1_0.txt or copy at
8
 * http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org/ for most recent version.
14
  *   FILE         basic_regex.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares template class basic_regex.
17
  */
18
19
#ifndef BOOST_REGEX_V5_BASIC_REGEX_HPP
20
#define BOOST_REGEX_V5_BASIC_REGEX_HPP
21
22
#include <vector>
23
24
namespace boost{
25
#ifdef BOOST_REGEX_MSVC
26
#pragma warning(push)
27
#pragma warning(disable : 4251)
28
#if BOOST_REGEX_MSVC < 1700
29
#     pragma warning(disable : 4231)
30
#endif
31
#if BOOST_REGEX_MSVC < 1600
32
#pragma warning(disable : 4660)
33
#endif
34
#if BOOST_REGEX_MSVC < 1910
35
#pragma warning(disable:4800)
36
#endif
37
#endif
38
39
namespace BOOST_REGEX_DETAIL_NS{
40
41
//
42
// forward declaration, we will need this one later:
43
//
44
template <class charT, class traits>
45
class basic_regex_parser;
46
47
template <class I>
48
void bubble_down_one(I first, I last)
49
0
{
50
0
   if(first != last)
51
0
   {
52
0
      I next = last - 1;
53
0
      while((next != first) && (*next < *(next-1)))
54
0
      {
55
0
         (next-1)->swap(*next);
56
0
         --next;
57
0
      }
58
0
   }
59
0
}
60
61
static const int hash_value_mask = 1 << (std::numeric_limits<int>::digits - 1);
62
63
template <class Iterator>
64
inline int hash_value_from_capture_name(Iterator i, Iterator j)
65
0
{
66
0
   std::size_t r = 0;
67
0
   while (i != j)
68
0
   {
69
0
      r ^= *i + 0x9e3779b9 + (r << 6) + (r >> 2);
70
0
      ++i;
71
0
   }
72
0
   r %= ((std::numeric_limits<int>::max)());
73
0
   return static_cast<int>(r) | hash_value_mask;
74
0
}
75
76
class named_subexpressions
77
{
78
public:
79
   struct name
80
   {
81
      template <class charT>
82
      name(const charT* i, const charT* j, int idx)
83
         : index(idx) 
84
0
      { 
85
0
         hash = hash_value_from_capture_name(i, j); 
86
0
      }
87
      name(int h, int idx)
88
         : index(idx), hash(h)
89
0
      { 
90
0
      }
91
      int index;
92
      int hash;
93
      bool operator < (const name& other)const
94
0
      {
95
0
         return hash < other.hash;
96
0
      }
97
      bool operator == (const name& other)const
98
0
      {
99
0
         return hash == other.hash; 
100
0
      }
101
      void swap(name& other)
102
0
      {
103
0
         std::swap(index, other.index);
104
0
         std::swap(hash, other.hash);
105
0
      }
106
   };
107
108
   typedef std::vector<name>::const_iterator const_iterator;
109
   typedef std::pair<const_iterator, const_iterator> range_type;
110
111
5
   named_subexpressions(){}
112
113
   template <class charT>
114
   void set_name(const charT* i, const charT* j, int index)
115
0
   {
116
0
      m_sub_names.push_back(name(i, j, index));
117
0
      bubble_down_one(m_sub_names.begin(), m_sub_names.end());
118
0
   }
119
   template <class charT>
120
   int get_id(const charT* i, const charT* j)const
121
   {
122
      name t(i, j, 0);
123
      typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
124
      if((pos != m_sub_names.end()) && (*pos == t))
125
      {
126
         return pos->index;
127
      }
128
      return -1;
129
   }
130
   template <class charT>
131
   range_type equal_range(const charT* i, const charT* j)const
132
   {
133
      name t(i, j, 0);
134
      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
135
   }
136
   int get_id(int h)const
137
0
   {
138
0
      name t(h, 0);
139
0
      std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
140
0
      if((pos != m_sub_names.end()) && (*pos == t))
141
0
      {
142
0
         return pos->index;
143
0
      }
144
0
      return -1;
145
0
   }
146
   range_type equal_range(int h)const
147
0
   {
148
0
      name t(h, 0);
149
0
      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
150
0
   }
151
private:
152
   std::vector<name> m_sub_names;
153
};
154
155
//
156
// class regex_data:
157
// represents the data we wish to expose to the matching algorithms.
158
//
159
template <class charT, class traits>
160
struct regex_data : public named_subexpressions
161
{
162
   typedef regex_constants::syntax_option_type   flag_type;
163
   typedef std::size_t                           size_type;  
164
165
   regex_data(const ::std::shared_ptr<
166
      ::boost::regex_traits_wrapper<traits> >& t) 
167
      : m_ptraits(t), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),
168
         m_mark_count(0), m_first_state(0), m_restart_type(0),
169
         m_startmap{ 0 },
170
0
         m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
171
   regex_data() 
172
      : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_flags(0), m_status(0), m_expression(0), m_expression_len(0), 
173
         m_mark_count(0), m_first_state(0), m_restart_type(0), 
174
      m_startmap{ 0 },
175
5
         m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
176
177
   ::std::shared_ptr<
178
      ::boost::regex_traits_wrapper<traits>
179
      >                        m_ptraits;                 // traits class instance
180
   flag_type                   m_flags;                   // flags with which we were compiled
181
   int                         m_status;                  // error code (0 implies OK).
182
   const charT*                m_expression;              // the original expression
183
   std::ptrdiff_t              m_expression_len;          // the length of the original expression
184
   size_type                   m_mark_count;              // the number of marked sub-expressions
185
   BOOST_REGEX_DETAIL_NS::re_syntax_base*  m_first_state;             // the first state of the machine
186
   unsigned                    m_restart_type;            // search optimisation type
187
   unsigned char               m_startmap[1 << CHAR_BIT]; // which characters can start a match
188
   unsigned int                m_can_be_null;             // whether we can match a null string
189
   BOOST_REGEX_DETAIL_NS::raw_storage      m_data;                    // the buffer in which our states are constructed
190
   typename traits::char_class_type    m_word_mask;       // mask used to determine if a character is a word character
191
   std::vector<
192
      std::pair<
193
      std::size_t, std::size_t> > m_subs;                 // Position of sub-expressions within the *string*.
194
   bool                        m_has_recursions;          // whether we have recursive expressions;
195
   bool                        m_disable_match_any;       // when set we need to disable the match_any flag as it causes different/buggy behaviour.
196
};
197
//
198
// class basic_regex_implementation
199
// pimpl implementation class for basic_regex.
200
//
201
template <class charT, class traits>
202
class basic_regex_implementation
203
   : public regex_data<charT, traits>
204
{
205
public:
206
   typedef regex_constants::syntax_option_type   flag_type;
207
   typedef std::ptrdiff_t                        difference_type;
208
   typedef std::size_t                           size_type; 
209
   typedef typename traits::locale_type          locale_type;
210
   typedef const charT*                          const_iterator;
211
212
5
   basic_regex_implementation(){}
213
   basic_regex_implementation(const ::std::shared_ptr<
214
      ::boost::regex_traits_wrapper<traits> >& t)
215
0
      : regex_data<charT, traits>(t) {}
216
   void assign(const charT* arg_first,
217
                          const charT* arg_last,
218
                          flag_type f)
219
5
   {
220
5
      regex_data<charT, traits>* pdat = this;
221
5
      basic_regex_parser<charT, traits> parser(pdat);
222
5
      parser.parse(arg_first, arg_last, f);
223
5
   }
224
225
   locale_type  imbue(locale_type l)
226
   { 
227
      return this->m_ptraits->imbue(l); 
228
   }
229
   locale_type  getloc()const
230
   { 
231
      return this->m_ptraits->getloc(); 
232
   }
233
   std::basic_string<charT>  str()const
234
   {
235
      std::basic_string<charT> result;
236
      if(this->m_status == 0)
237
         result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
238
      return result;
239
   }
240
   const_iterator  expression()const
241
   {
242
      return this->m_expression;
243
   }
244
   std::pair<const_iterator, const_iterator>  subexpression(std::size_t n)const
245
   {
246
      const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);
247
      std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);
248
      return p;
249
   }
250
   //
251
   // begin, end:
252
   const_iterator  begin()const
253
   { 
254
      return (this->m_status ? 0 : this->m_expression); 
255
   }
256
   const_iterator  end()const
257
   { 
258
      return (this->m_status ? 0 : this->m_expression + this->m_expression_len); 
259
   }
260
   flag_type  flags()const
261
10
   {
262
10
      return this->m_flags;
263
10
   }
264
   size_type  size()const
265
5
   {
266
5
      return this->m_expression_len;
267
5
   }
268
   int  status()const
269
5
   {
270
5
      return this->m_status;
271
5
   }
272
   size_type  mark_count()const
273
5
   {
274
5
      return this->m_mark_count - 1;
275
5
   }
276
   const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
277
5
   {
278
5
      return this->m_first_state;
279
5
   }
280
   unsigned get_restart_type()const
281
   {
282
      return this->m_restart_type;
283
   }
284
   const unsigned char* get_map()const
285
   {
286
      return this->m_startmap;
287
   }
288
   const ::boost::regex_traits_wrapper<traits>& get_traits()const
289
5
   {
290
5
      return *(this->m_ptraits);
291
5
   }
292
   bool can_be_null()const
293
   {
294
      return this->m_can_be_null;
295
   }
296
   const regex_data<charT, traits>& get_data()const
297
10
   {
298
10
      basic_regex_implementation<charT, traits> const* p = this;
299
10
      return *static_cast<const regex_data<charT, traits>*>(p);
300
10
   }
301
};
302
303
} // namespace BOOST_REGEX_DETAIL_NS
304
//
305
// class basic_regex:
306
// represents the compiled
307
// regular expression:
308
//
309
310
#ifdef BOOST_REGEX_NO_FWD
311
template <class charT, class traits = regex_traits<charT> >
312
#else
313
template <class charT, class traits >
314
#endif
315
class basic_regex : public regbase
316
{
317
public:
318
   // typedefs:
319
   typedef std::size_t                           traits_size_type;
320
   typedef typename traits::string_type          traits_string_type;
321
   typedef charT                                 char_type;
322
   typedef traits                                traits_type;
323
324
   typedef charT                                 value_type;
325
   typedef charT&                                reference;
326
   typedef const charT&                          const_reference;
327
   typedef const charT*                          const_iterator;
328
   typedef const_iterator                        iterator;
329
   typedef std::ptrdiff_t                        difference_type;
330
   typedef std::size_t                           size_type;   
331
   typedef regex_constants::syntax_option_type   flag_type;
332
   // locale_type
333
   // placeholder for actual locale type used by the
334
   // traits class to localise *this.
335
   typedef typename traits::locale_type          locale_type;
336
   
337
public:
338
   explicit basic_regex(){}
339
   explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
340
5
   {
341
5
      assign(p, f);
342
5
   }
343
   basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
344
   {
345
      assign(p1, p2, f);
346
   }
347
   basic_regex(const charT* p, size_type len, flag_type f)
348
   {
349
      assign(p, len, f);
350
   }
351
   basic_regex(const basic_regex& that)
352
      : m_pimpl(that.m_pimpl) {}
353
5
   ~basic_regex(){}
354
   basic_regex&  operator=(const basic_regex& that)
355
   {
356
      return assign(that);
357
   }
358
   basic_regex&  operator=(const charT* ptr)
359
   {
360
      return assign(ptr);
361
   }
362
363
   //
364
   // assign:
365
   basic_regex& assign(const basic_regex& that)
366
   { 
367
      m_pimpl = that.m_pimpl;
368
      return *this; 
369
   }
370
   basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
371
5
   {
372
5
      return assign(p, p + traits::length(p), f);
373
5
   }
374
   basic_regex& assign(const charT* p, size_type len, flag_type f)
375
   {
376
      return assign(p, p + len, f);
377
   }
378
private:
379
   basic_regex& do_assign(const charT* p1,
380
                          const charT* p2,
381
                          flag_type f);
382
public:
383
   basic_regex& assign(const charT* p1,
384
                          const charT* p2,
385
                          flag_type f = regex_constants::normal)
386
5
   {
387
5
      return do_assign(p1, p2, f);
388
5
   }
389
390
   template <class ST, class SA>
391
   unsigned int  set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
392
   { 
393
      return set_expression(p.data(), p.data() + p.size(), f); 
394
   }
395
396
   template <class ST, class SA>
397
   explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
398
   { 
399
      assign(p, f); 
400
   }
401
402
   template <class InputIterator>
403
   basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
404
   {
405
      typedef typename traits::string_type seq_type;
406
      seq_type a(arg_first, arg_last);
407
      if(!a.empty())
408
         assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);
409
      else
410
         assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
411
   }
412
413
   template <class ST, class SA>
414
   basic_regex&  operator=(const std::basic_string<charT, ST, SA>& p)
415
   {
416
      return assign(p.data(), p.data() + p.size(), regex_constants::normal);
417
   }
418
419
   template <class string_traits, class A>
420
   basic_regex&  assign(
421
       const std::basic_string<charT, string_traits, A>& s,
422
       flag_type f = regex_constants::normal)
423
   {
424
      return assign(s.data(), s.data() + s.size(), f);
425
   }
426
427
   template <class InputIterator>
428
   basic_regex&  assign(InputIterator arg_first,
429
                          InputIterator arg_last,
430
                          flag_type f = regex_constants::normal)
431
   {
432
      typedef typename traits::string_type seq_type;
433
      seq_type a(arg_first, arg_last);
434
      if(a.size())
435
      {
436
         const charT* p1 = &*a.begin();
437
         const charT* p2 = &*a.begin() + a.size();
438
         return assign(p1, p2, f);
439
      }
440
      return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
441
   }
442
443
   //
444
   // locale:
445
   locale_type  imbue(locale_type l);
446
   locale_type  getloc()const
447
   { 
448
      return m_pimpl.get() ? m_pimpl->getloc() : locale_type(); 
449
   }
450
   //
451
   // getflags:
452
   // retained for backwards compatibility only, "flags"
453
   // is now the preferred name:
454
   flag_type  getflags()const
455
   { 
456
      return flags();
457
   }
458
   flag_type  flags()const
459
10
   { 
460
10
      return m_pimpl.get() ? m_pimpl->flags() : 0;
461
10
   }
462
   //
463
   // str:
464
   std::basic_string<charT>  str()const
465
   {
466
      return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
467
   }
468
   //
469
   // begin, end, subexpression:
470
   std::pair<const_iterator, const_iterator>  subexpression(std::size_t n)const
471
   {
472
#ifdef BOOST_REGEX_STANDALONE
473
      if (!m_pimpl.get())
474
         throw std::logic_error("Can't access subexpressions in an invalid regex.");
475
#else
476
      if(!m_pimpl.get())
477
         boost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));
478
#endif
479
      return m_pimpl->subexpression(n);
480
   }
481
   const_iterator  begin()const
482
   { 
483
      return (m_pimpl.get() ? m_pimpl->begin() : 0); 
484
   }
485
   const_iterator  end()const
486
   { 
487
      return (m_pimpl.get() ? m_pimpl->end() : 0); 
488
   }
489
   //
490
   // swap:
491
   void  swap(basic_regex& that)throw()
492
   {
493
      m_pimpl.swap(that.m_pimpl);
494
   }
495
   //
496
   // size:
497
   size_type  size()const
498
5
   { 
499
5
      return (m_pimpl.get() ? m_pimpl->size() : 0); 
500
5
   }
501
   //
502
   // max_size:
503
   size_type  max_size()const
504
   { 
505
      return UINT_MAX; 
506
   }
507
   //
508
   // empty:
509
   bool  empty()const
510
5
   { 
511
5
      return (m_pimpl.get() ? 0 != m_pimpl->status() : true); 
512
5
   }
513
514
   size_type  mark_count()const 
515
5
   { 
516
5
      return (m_pimpl.get() ? m_pimpl->mark_count() : 0); 
517
5
   }
518
519
   int status()const
520
   {
521
      return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
522
   }
523
524
   int  compare(const basic_regex& that) const
525
   {
526
      if(m_pimpl.get() == that.m_pimpl.get())
527
         return 0;
528
      if(!m_pimpl.get())
529
         return -1;
530
      if(!that.m_pimpl.get())
531
         return 1;
532
      if(status() != that.status())
533
         return status() - that.status();
534
      if(flags() != that.flags())
535
         return flags() - that.flags();
536
      return str().compare(that.str());
537
   }
538
   bool  operator==(const basic_regex& e)const
539
   { 
540
      return compare(e) == 0; 
541
   }
542
   bool  operator != (const basic_regex& e)const
543
   { 
544
      return compare(e) != 0; 
545
   }
546
   bool  operator<(const basic_regex& e)const
547
   { 
548
      return compare(e) < 0; 
549
   }
550
   bool  operator>(const basic_regex& e)const
551
   { 
552
      return compare(e) > 0; 
553
   }
554
   bool  operator<=(const basic_regex& e)const
555
   { 
556
      return compare(e) <= 0; 
557
   }
558
   bool  operator>=(const basic_regex& e)const
559
   { 
560
      return compare(e) >= 0; 
561
   }
562
563
   //
564
   // The following are deprecated as public interfaces
565
   // but are available for compatibility with earlier versions.
566
   const charT*  expression()const 
567
   { 
568
      return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0); 
569
   }
570
   unsigned int  set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
571
   {
572
      assign(p1, p2, f | regex_constants::no_except);
573
      return status();
574
   }
575
   unsigned int  set_expression(const charT* p, flag_type f = regex_constants::normal) 
576
   { 
577
      assign(p, f | regex_constants::no_except); 
578
      return status();
579
   }
580
   unsigned int  error_code()const
581
   {
582
      return status();
583
   }
584
   //
585
   // private access methods:
586
   //
587
   const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
588
5
   {
589
5
      BOOST_REGEX_ASSERT(0 != m_pimpl.get());
590
0
      return m_pimpl->get_first_state();
591
5
   }
592
   unsigned get_restart_type()const
593
   {
594
      BOOST_REGEX_ASSERT(0 != m_pimpl.get());
595
      return m_pimpl->get_restart_type();
596
   }
597
   const unsigned char* get_map()const
598
   {
599
      BOOST_REGEX_ASSERT(0 != m_pimpl.get());
600
      return m_pimpl->get_map();
601
   }
602
   const ::boost::regex_traits_wrapper<traits>& get_traits()const
603
5
   {
604
5
      BOOST_REGEX_ASSERT(0 != m_pimpl.get());
605
0
      return m_pimpl->get_traits();
606
5
   }
607
   bool can_be_null()const
608
   {
609
      BOOST_REGEX_ASSERT(0 != m_pimpl.get());
610
      return m_pimpl->can_be_null();
611
   }
612
   const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const
613
10
   {
614
10
      BOOST_REGEX_ASSERT(0 != m_pimpl.get());
615
0
      return m_pimpl->get_data();
616
10
   }
617
   std::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const
618
5
   {
619
5
      return m_pimpl;
620
5
   }
621
622
private:
623
   std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;
624
};
625
626
//
627
// out of line members;
628
// these are the only members that mutate the basic_regex object,
629
// and are designed to provide the strong exception guarantee
630
// (in the event of a throw, the state of the object remains unchanged).
631
//
632
template <class charT, class traits>
633
basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
634
                        const charT* p2,
635
                        flag_type f)
636
5
{
637
5
   std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;
638
5
   if(!m_pimpl.get())
639
5
   {
640
5
      temp = std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
641
5
   }
642
0
   else
643
0
   {
644
0
      temp = std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
645
0
   }
646
5
   temp->assign(p1, p2, f);
647
5
   temp.swap(m_pimpl);
648
5
   return *this;
649
5
}
650
651
template <class charT, class traits>
652
typename basic_regex<charT, traits>::locale_type  basic_regex<charT, traits>::imbue(locale_type l)
653
{ 
654
   std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
655
   locale_type result = temp->imbue(l);
656
   temp.swap(m_pimpl);
657
   return result;
658
}
659
660
//
661
// non-members:
662
//
663
template <class charT, class traits>
664
void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
665
{
666
   e1.swap(e2);
667
}
668
669
template <class charT, class traits, class traits2>
670
std::basic_ostream<charT, traits>& 
671
   operator << (std::basic_ostream<charT, traits>& os, 
672
                const basic_regex<charT, traits2>& e)
673
{
674
   return (os << e.str());
675
}
676
677
//
678
// class reg_expression:
679
// this is provided for backwards compatibility only,
680
// it is deprecated, no not use!
681
//
682
#ifdef BOOST_REGEX_NO_FWD
683
template <class charT, class traits = regex_traits<charT> >
684
#else
685
template <class charT, class traits >
686
#endif
687
class reg_expression : public basic_regex<charT, traits>
688
{
689
public:
690
   typedef typename basic_regex<charT, traits>::flag_type flag_type;
691
   typedef typename basic_regex<charT, traits>::size_type size_type;
692
   explicit reg_expression(){}
693
   explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
694
      : basic_regex<charT, traits>(p, f){}
695
   reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
696
      : basic_regex<charT, traits>(p1, p2, f){}
697
   reg_expression(const charT* p, size_type len, flag_type f)
698
      : basic_regex<charT, traits>(p, len, f){}
699
   reg_expression(const reg_expression& that)
700
      : basic_regex<charT, traits>(that) {}
701
   ~reg_expression(){}
702
   reg_expression&  operator=(const reg_expression& that)
703
   {
704
      return this->assign(that);
705
   }
706
707
   template <class ST, class SA>
708
   explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
709
   : basic_regex<charT, traits>(p, f)
710
   { 
711
   }
712
713
   template <class InputIterator>
714
   reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
715
   : basic_regex<charT, traits>(arg_first, arg_last, f)
716
   {
717
   }
718
719
   template <class ST, class SA>
720
   reg_expression&  operator=(const std::basic_string<charT, ST, SA>& p)
721
   {
722
      this->assign(p);
723
      return *this;
724
   }
725
726
};
727
728
#ifdef BOOST_REGEX_MSVC
729
#pragma warning (pop)
730
#endif
731
732
} // namespace boost
733
734
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/basic_regex_creator.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2004
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         basic_regex_creator.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares template class basic_regex_creator which fills in
17
  *                the data members of a regex_data object.
18
  */
19
20
#ifndef BOOST_REGEX_V5_BASIC_REGEX_CREATOR_HPP
21
#define BOOST_REGEX_V5_BASIC_REGEX_CREATOR_HPP
22
23
#include <boost/regex/v5/indexed_bit_flag.hpp>
24
25
#ifdef BOOST_REGEX_MSVC
26
#  pragma warning(push)
27
#pragma warning(disable:4459)
28
#if BOOST_REGEX_MSVC < 1910
29
#pragma warning(disable:4800)
30
#endif
31
#endif
32
33
namespace boost{
34
35
namespace BOOST_REGEX_DETAIL_NS{
36
37
template <class charT>
38
struct digraph : public std::pair<charT, charT>
39
{
40
10
   digraph() : std::pair<charT, charT>(charT(0), charT(0)){}
41
10
   digraph(charT c1) : std::pair<charT, charT>(c1, charT(0)){}
42
   digraph(charT c1, charT c2) : std::pair<charT, charT>(c1, c2)
43
   {}
44
15
   digraph(const digraph<charT>& d) : std::pair<charT, charT>(d.first, d.second){}
45
10
   digraph<charT>& operator=(const digraph<charT>&) = default;
46
   template <class Seq>
47
   digraph(const Seq& s) : std::pair<charT, charT>()
48
   {
49
      BOOST_REGEX_ASSERT(s.size() <= 2);
50
      BOOST_REGEX_ASSERT(s.size());
51
      this->first = s[0];
52
      this->second = (s.size() > 1) ? s[1] : 0;
53
   }
54
};
55
56
template <class charT, class traits>
57
class basic_char_set
58
{
59
public:
60
   typedef digraph<charT>                   digraph_type;
61
   typedef typename traits::string_type     string_type;
62
   typedef typename traits::char_class_type m_type;
63
64
   basic_char_set()
65
5
   {
66
5
      m_negate = false;
67
5
      m_has_digraphs = false;
68
5
      m_classes = 0;
69
5
      m_negated_classes = 0;
70
5
      m_empty = true;
71
5
   }
72
73
   void add_single(const digraph_type& s)
74
0
   {
75
0
      m_singles.insert(s);
76
0
      if(s.second)
77
0
         m_has_digraphs = true;
78
0
      m_empty = false;
79
0
   }
80
   void add_range(const digraph_type& first, const digraph_type& end)
81
5
   {
82
5
      m_ranges.push_back(first);
83
5
      m_ranges.push_back(end);
84
5
      if(first.second)
85
0
      {
86
0
         m_has_digraphs = true;
87
0
         add_single(first);
88
0
      }
89
5
      if(end.second)
90
0
      {
91
0
         m_has_digraphs = true;
92
0
         add_single(end);
93
0
      }
94
5
      m_empty = false;
95
5
   }
96
   void add_class(m_type m)
97
0
   {
98
0
      m_classes |= m;
99
0
      m_empty = false;
100
0
   }
101
   void add_negated_class(m_type m)
102
0
   {
103
0
      m_negated_classes |= m;
104
0
      m_empty = false;
105
0
   }
106
   void add_equivalent(const digraph_type& s)
107
0
   {
108
0
      m_equivalents.insert(s);
109
0
      if(s.second)
110
0
      {
111
0
         m_has_digraphs = true;
112
0
         add_single(s);
113
0
      }
114
0
      m_empty = false;
115
0
   }
116
   void negate()
117
0
   { 
118
0
      m_negate = true;
119
      //m_empty = false;
120
0
   }
121
122
   //
123
   // accessor functions:
124
   //
125
   bool has_digraphs()const
126
5
   {
127
5
      return m_has_digraphs;
128
5
   }
129
   bool is_negated()const
130
5
   {
131
5
      return m_negate;
132
5
   }
133
   typedef typename std::vector<digraph_type>::const_iterator  list_iterator;
134
   typedef typename std::set<digraph_type>::const_iterator     set_iterator;
135
   set_iterator singles_begin()const
136
5
   {
137
5
      return m_singles.begin();
138
5
   }
139
   set_iterator singles_end()const
140
5
   {
141
5
      return m_singles.end();
142
5
   }
143
   list_iterator ranges_begin()const
144
5
   {
145
5
      return m_ranges.begin();
146
5
   }
147
   list_iterator ranges_end()const
148
5
   {
149
5
      return m_ranges.end();
150
5
   }
151
   set_iterator equivalents_begin()const
152
5
   {
153
5
      return m_equivalents.begin();
154
5
   }
155
   set_iterator equivalents_end()const
156
5
   {
157
5
      return m_equivalents.end();
158
5
   }
159
   m_type classes()const
160
5
   {
161
5
      return m_classes;
162
5
   }
163
   m_type negated_classes()const
164
5
   {
165
5
      return m_negated_classes;
166
5
   }
167
   bool empty()const
168
0
   {
169
0
      return m_empty;
170
0
   }
171
private:
172
   std::set<digraph_type>    m_singles;         // a list of single characters to match
173
   std::vector<digraph_type> m_ranges;          // a list of end points of our ranges
174
   bool                      m_negate;          // true if the set is to be negated
175
   bool                      m_has_digraphs;    // true if we have digraphs present
176
   m_type                    m_classes;         // character classes to match
177
   m_type                    m_negated_classes; // negated character classes to match
178
   bool                      m_empty;           // whether we've added anything yet
179
   std::set<digraph_type>    m_equivalents;     // a list of equivalence classes
180
};
181
   
182
template <class charT, class traits>
183
class basic_regex_creator
184
{
185
public:
186
   basic_regex_creator(regex_data<charT, traits>* data);
187
   std::ptrdiff_t getoffset(void* addr)
188
105
   {
189
105
      return getoffset(addr, m_pdata->m_data.data());
190
105
   }
191
   std::ptrdiff_t getoffset(const void* addr, const void* base)
192
105
   {
193
105
      return static_cast<const char*>(addr) - static_cast<const char*>(base);
194
105
   }
195
   re_syntax_base* getaddress(std::ptrdiff_t off)
196
20
   {
197
20
      return getaddress(off, m_pdata->m_data.data());
198
20
   }
199
   re_syntax_base* getaddress(std::ptrdiff_t off, void* base)
200
105
   {
201
105
      return static_cast<re_syntax_base*>(static_cast<void*>(static_cast<char*>(base) + off));
202
105
   }
203
   void init(unsigned l_flags)
204
5
   {
205
5
      m_pdata->m_flags = l_flags;
206
5
      m_icase = l_flags & regex_constants::icase;
207
5
   }
208
   regbase::flag_type flags()
209
105
   {
210
105
      return m_pdata->m_flags;
211
105
   }
212
   void flags(regbase::flag_type f)
213
10
   {
214
10
      m_pdata->m_flags = f;
215
10
      if(m_icase != static_cast<bool>(f & regbase::icase))
216
0
      {
217
0
         m_icase = static_cast<bool>(f & regbase::icase);
218
0
      }
219
10
   }
220
   re_syntax_base* append_state(syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
221
   re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
222
   re_literal* append_literal(charT c);
223
   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set);
224
   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, std::integral_constant<bool, false>*);
225
   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, std::integral_constant<bool, true>*);
226
   void finalize(const charT* p1, const charT* p2);
227
protected:
228
   regex_data<charT, traits>*    m_pdata;              // pointer to the basic_regex_data struct we are filling in
229
   const ::boost::regex_traits_wrapper<traits>&  
230
                                 m_traits;             // convenience reference to traits class
231
   re_syntax_base*               m_last_state;         // the last state we added
232
   bool                          m_icase;              // true for case insensitive matches
233
   unsigned                      m_repeater_id;        // the state_id of the next repeater
234
   bool                          m_has_backrefs;       // true if there are actually any backrefs
235
   indexed_bit_flag              m_backrefs;           // bitmask of permitted backrefs
236
   std::uintmax_t                m_bad_repeats;        // bitmask of repeats we can't deduce a startmap for;
237
   bool                          m_has_recursions;     // set when we have recursive expressions to fixup
238
   std::vector<unsigned char>    m_recursion_checks;   // notes which recursions we've followed while analysing this expression
239
   typename traits::char_class_type m_word_mask;       // mask used to determine if a character is a word character
240
   typename traits::char_class_type m_mask_space;      // mask used to determine if a character is a word character
241
   typename traits::char_class_type m_lower_mask;       // mask used to determine if a character is a lowercase character
242
   typename traits::char_class_type m_upper_mask;      // mask used to determine if a character is an uppercase character
243
   typename traits::char_class_type m_alpha_mask;      // mask used to determine if a character is an alphabetic character
244
private:
245
   basic_regex_creator& operator=(const basic_regex_creator&);
246
   basic_regex_creator(const basic_regex_creator&);
247
248
   void fixup_pointers(re_syntax_base* state);
249
   void fixup_recursions(re_syntax_base* state);
250
   void create_startmaps(re_syntax_base* state);
251
   int calculate_backstep(re_syntax_base* state);
252
   void create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask);
253
   unsigned get_restart_type(re_syntax_base* state);
254
   void set_all_masks(unsigned char* bits, unsigned char);
255
   bool is_bad_repeat(re_syntax_base* pt);
256
   void set_bad_repeat(re_syntax_base* pt);
257
   syntax_element_type get_repeat_type(re_syntax_base* state);
258
   void probe_leading_repeat(re_syntax_base* state);
259
};
260
261
template <class charT, class traits>
262
basic_regex_creator<charT, traits>::basic_regex_creator(regex_data<charT, traits>* data)
263
   : m_pdata(data), m_traits(*(data->m_ptraits)), m_last_state(0), m_icase(false), m_repeater_id(0), 
264
   m_has_backrefs(false), m_bad_repeats(0), m_has_recursions(false), m_word_mask(0), m_mask_space(0), m_lower_mask(0), m_upper_mask(0), m_alpha_mask(0)
265
5
{
266
5
   m_pdata->m_data.clear();
267
5
   m_pdata->m_status = ::boost::regex_constants::error_ok;
268
5
   static const charT w = 'w';
269
5
   static const charT s = 's';
270
5
   static const charT l[5] = { 'l', 'o', 'w', 'e', 'r', };
271
5
   static const charT u[5] = { 'u', 'p', 'p', 'e', 'r', };
272
5
   static const charT a[5] = { 'a', 'l', 'p', 'h', 'a', };
273
5
   m_word_mask = m_traits.lookup_classname(&w, &w +1);
274
5
   m_mask_space = m_traits.lookup_classname(&s, &s +1);
275
5
   m_lower_mask = m_traits.lookup_classname(l, l + 5);
276
5
   m_upper_mask = m_traits.lookup_classname(u, u + 5);
277
5
   m_alpha_mask = m_traits.lookup_classname(a, a + 5);
278
5
   m_pdata->m_word_mask = m_word_mask;
279
5
   BOOST_REGEX_ASSERT(m_word_mask != 0); 
280
5
   BOOST_REGEX_ASSERT(m_mask_space != 0); 
281
5
   BOOST_REGEX_ASSERT(m_lower_mask != 0); 
282
5
   BOOST_REGEX_ASSERT(m_upper_mask != 0); 
283
5
   BOOST_REGEX_ASSERT(m_alpha_mask != 0); 
284
5
}
285
286
template <class charT, class traits>
287
re_syntax_base* basic_regex_creator<charT, traits>::append_state(syntax_element_type t, std::size_t s)
288
60
{
289
   // if the state is a backref then make a note of it:
290
60
   if(t == syntax_element_backref)
291
0
      this->m_has_backrefs = true;
292
   // append a new state, start by aligning our last one:
293
60
   m_pdata->m_data.align();
294
   // set the offset to the next state in our last one:
295
60
   if(m_last_state)
296
55
      m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);
297
   // now actually extend our data:
298
60
   m_last_state = static_cast<re_syntax_base*>(m_pdata->m_data.extend(s));
299
   // fill in boilerplate options in the new state:
300
60
   m_last_state->next.i = 0;
301
60
   m_last_state->type = t;
302
60
   return m_last_state;
303
60
}
304
305
template <class charT, class traits>
306
re_syntax_base* basic_regex_creator<charT, traits>::insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s)
307
10
{
308
   // append a new state, start by aligning our last one:
309
10
   m_pdata->m_data.align();
310
   // set the offset to the next state in our last one:
311
10
   if(m_last_state)
312
10
      m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);
313
   // remember the last state position:
314
10
   std::ptrdiff_t off = getoffset(m_last_state) + s;
315
   // now actually insert our data:
316
10
   re_syntax_base* new_state = static_cast<re_syntax_base*>(m_pdata->m_data.insert(pos, s));
317
   // fill in boilerplate options in the new state:
318
10
   new_state->next.i = s;
319
10
   new_state->type = t;
320
10
   m_last_state = getaddress(off);
321
10
   return new_state;
322
10
}
323
324
template <class charT, class traits>
325
re_literal* basic_regex_creator<charT, traits>::append_literal(charT c)
326
15
{
327
15
   re_literal* result;
328
   // start by seeing if we have an existing re_literal we can extend:
329
15
   if((0 == m_last_state) || (m_last_state->type != syntax_element_literal))
330
15
   {
331
      // no existing re_literal, create a new one:
332
15
      result = static_cast<re_literal*>(append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
333
15
      result->length = 1;
334
15
      *static_cast<charT*>(static_cast<void*>(result+1)) = m_traits.translate(c, m_icase);
335
15
   }
336
0
   else
337
0
   {
338
      // we have an existing re_literal, extend it:
339
0
      std::ptrdiff_t off = getoffset(m_last_state);
340
0
      m_pdata->m_data.extend(sizeof(charT));
341
0
      m_last_state = result = static_cast<re_literal*>(getaddress(off));
342
0
      charT* characters = static_cast<charT*>(static_cast<void*>(result+1));
343
0
      characters[result->length] = m_traits.translate(c, m_icase);
344
0
      result->length += 1;
345
0
   }
346
15
   return result;
347
15
}
348
349
template <class charT, class traits>
350
inline re_syntax_base* basic_regex_creator<charT, traits>::append_set(
351
   const basic_char_set<charT, traits>& char_set)
352
5
{
353
5
   typedef std::integral_constant<bool, (sizeof(charT) == 1) > truth_type;
354
5
   return char_set.has_digraphs() 
355
5
      ? append_set(char_set, static_cast<std::integral_constant<bool, false>*>(0))
356
5
      : append_set(char_set, static_cast<truth_type*>(0));
357
5
}
358
359
template <class charT, class traits>
360
re_syntax_base* basic_regex_creator<charT, traits>::append_set(
361
   const basic_char_set<charT, traits>& char_set, std::integral_constant<bool, false>*)
362
0
{
363
0
   typedef typename traits::string_type string_type;
364
0
   typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;
365
0
   typedef typename basic_char_set<charT, traits>::set_iterator  set_iterator;
366
0
   typedef typename traits::char_class_type m_type;
367
   
368
0
   re_set_long<m_type>* result = static_cast<re_set_long<m_type>*>(append_state(syntax_element_long_set, sizeof(re_set_long<m_type>)));
369
   //
370
   // fill in the basics:
371
   //
372
0
   result->csingles = static_cast<unsigned int>(std::distance(char_set.singles_begin(), char_set.singles_end()));
373
0
   result->cranges = static_cast<unsigned int>(std::distance(char_set.ranges_begin(), char_set.ranges_end())) / 2;
374
0
   result->cequivalents = static_cast<unsigned int>(std::distance(char_set.equivalents_begin(), char_set.equivalents_end()));
375
0
   result->cclasses = char_set.classes();
376
0
   result->cnclasses = char_set.negated_classes();
377
0
   if(flags() & regbase::icase)
378
0
   {
379
      // adjust classes as needed:
380
0
      if(((result->cclasses & m_lower_mask) == m_lower_mask) || ((result->cclasses & m_upper_mask) == m_upper_mask))
381
0
         result->cclasses |= m_alpha_mask;
382
0
      if(((result->cnclasses & m_lower_mask) == m_lower_mask) || ((result->cnclasses & m_upper_mask) == m_upper_mask))
383
0
         result->cnclasses |= m_alpha_mask;
384
0
   }
385
386
0
   result->isnot = char_set.is_negated();
387
0
   result->singleton = !char_set.has_digraphs();
388
   //
389
   // remember where the state is for later:
390
   //
391
0
   std::ptrdiff_t offset = getoffset(result);
392
   //
393
   // now extend with all the singles:
394
   //
395
0
   item_iterator first, last;
396
0
   set_iterator sfirst, slast;
397
0
   sfirst = char_set.singles_begin();
398
0
   slast = char_set.singles_end();
399
0
   while(sfirst != slast)
400
0
   {
401
0
      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (sfirst->first == static_cast<charT>(0) ? 1 : sfirst->second ? 3 : 2)));
402
0
      p[0] = m_traits.translate(sfirst->first, m_icase);
403
0
      if(sfirst->first == static_cast<charT>(0))
404
0
      {
405
0
         p[0] = 0;
406
0
      }
407
0
      else if(sfirst->second)
408
0
      {
409
0
         p[1] = m_traits.translate(sfirst->second, m_icase);
410
0
         p[2] = 0;
411
0
      }
412
0
      else
413
0
         p[1] = 0;
414
0
      ++sfirst;
415
0
   }
416
   //
417
   // now extend with all the ranges:
418
   //
419
0
   first = char_set.ranges_begin();
420
0
   last = char_set.ranges_end();
421
0
   while(first != last)
422
0
   {
423
      // first grab the endpoints of the range:
424
0
      digraph<charT> c1 = *first;
425
0
      c1.first = this->m_traits.translate(c1.first, this->m_icase);
426
0
      c1.second = this->m_traits.translate(c1.second, this->m_icase);
427
0
      ++first;
428
0
      digraph<charT> c2 = *first;
429
0
      c2.first = this->m_traits.translate(c2.first, this->m_icase);
430
0
      c2.second = this->m_traits.translate(c2.second, this->m_icase);
431
0
      ++first;
432
0
      string_type s1, s2;
433
      // different actions now depending upon whether collation is turned on:
434
0
      if(flags() & regex_constants::collate)
435
0
      {
436
         // we need to transform our range into sort keys:
437
0
         charT a1[3] = { c1.first, c1.second, charT(0), };
438
0
         charT a2[3] = { c2.first, c2.second, charT(0), };
439
0
         s1 = this->m_traits.transform(a1, (a1[1] ? a1+2 : a1+1));
440
0
         s2 = this->m_traits.transform(a2, (a2[1] ? a2+2 : a2+1));
441
0
         if(s1.empty())
442
0
            s1 = string_type(1, charT(0));
443
0
         if(s2.empty())
444
0
            s2 = string_type(1, charT(0));
445
0
      }
446
0
      else
447
0
      {
448
0
         if(c1.second)
449
0
         {
450
0
            s1.insert(s1.end(), c1.first);
451
0
            s1.insert(s1.end(), c1.second);
452
0
         }
453
0
         else
454
0
            s1 = string_type(1, c1.first);
455
0
         if(c2.second)
456
0
         {
457
0
            s2.insert(s2.end(), c2.first);
458
0
            s2.insert(s2.end(), c2.second);
459
0
         }
460
0
         else
461
0
            s2.insert(s2.end(), c2.first);
462
0
      }
463
0
      if(s1 > s2)
464
0
      {
465
         // Oops error:
466
0
         return 0;
467
0
      }
468
0
      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s1.size() + s2.size() + 2) ) );
469
0
      BOOST_REGEX_DETAIL_NS::copy(s1.begin(), s1.end(), p);
470
0
      p[s1.size()] = charT(0);
471
0
      p += s1.size() + 1;
472
0
      BOOST_REGEX_DETAIL_NS::copy(s2.begin(), s2.end(), p);
473
0
      p[s2.size()] = charT(0);
474
0
   }
475
   //
476
   // now process the equivalence classes:
477
   //
478
0
   sfirst = char_set.equivalents_begin();
479
0
   slast = char_set.equivalents_end();
480
0
   while(sfirst != slast)
481
0
   {
482
0
      string_type s;
483
0
      if(sfirst->second)
484
0
      {
485
0
         charT cs[3] = { sfirst->first, sfirst->second, charT(0), };
486
0
         s = m_traits.transform_primary(cs, cs+2);
487
0
      }
488
0
      else
489
0
         s = m_traits.transform_primary(&sfirst->first, &sfirst->first+1);
490
0
      if(s.empty())
491
0
         return 0;  // invalid or unsupported equivalence class
492
0
      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s.size()+1) ) );
493
0
      BOOST_REGEX_DETAIL_NS::copy(s.begin(), s.end(), p);
494
0
      p[s.size()] = charT(0);
495
0
      ++sfirst;
496
0
   }
497
   //
498
   // finally reset the address of our last state:
499
   //
500
0
   m_last_state = result = static_cast<re_set_long<m_type>*>(getaddress(offset));
501
0
   return result;
502
0
}
503
504
template<class T>
505
inline bool char_less(T t1, T t2)
506
{
507
   return t1 < t2;
508
}
509
inline bool char_less(char t1, char t2)
510
5
{
511
5
   return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);
512
5
}
513
inline bool char_less(signed char t1, signed char t2)
514
0
{
515
0
   return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);
516
0
}
517
518
template <class charT, class traits>
519
re_syntax_base* basic_regex_creator<charT, traits>::append_set(
520
   const basic_char_set<charT, traits>& char_set, std::integral_constant<bool, true>*)
521
5
{
522
5
   typedef typename traits::string_type string_type;
523
5
   typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;
524
5
   typedef typename basic_char_set<charT, traits>::set_iterator set_iterator;
525
526
5
   re_set* result = static_cast<re_set*>(append_state(syntax_element_set, sizeof(re_set)));
527
5
   bool negate = char_set.is_negated();
528
5
   std::memset(result->_map, 0, sizeof(result->_map));
529
   //
530
   // handle singles first:
531
   //
532
5
   item_iterator first, last;
533
5
   set_iterator sfirst, slast;
534
5
   sfirst = char_set.singles_begin();
535
5
   slast = char_set.singles_end();
536
5
   while(sfirst != slast)
537
0
   {
538
0
      for(unsigned int i = 0; i < (1 << CHAR_BIT); ++i)
539
0
      {
540
0
         if(this->m_traits.translate(static_cast<charT>(i), this->m_icase)
541
0
            == this->m_traits.translate(sfirst->first, this->m_icase))
542
0
            result->_map[i] = true;
543
0
      }
544
0
      ++sfirst;
545
0
   }
546
   //
547
   // OK now handle ranges:
548
   //
549
5
   first = char_set.ranges_begin();
550
5
   last = char_set.ranges_end();
551
10
   while(first != last)
552
5
   {
553
      // first grab the endpoints of the range:
554
5
      charT c1 = this->m_traits.translate(first->first, this->m_icase);
555
5
      ++first;
556
5
      charT c2 = this->m_traits.translate(first->first, this->m_icase);
557
5
      ++first;
558
      // different actions now depending upon whether collation is turned on:
559
5
      if(flags() & regex_constants::collate)
560
0
      {
561
         // we need to transform our range into sort keys:
562
0
         charT c3[2] = { c1, charT(0), };
563
0
         string_type s1 = this->m_traits.transform(c3, c3+1);
564
0
         c3[0] = c2;
565
0
         string_type s2 = this->m_traits.transform(c3, c3+1);
566
0
         if(s1 > s2)
567
0
         {
568
            // Oops error:
569
0
            return 0;
570
0
         }
571
0
         BOOST_REGEX_ASSERT(c3[1] == charT(0));
572
0
         for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
573
0
         {
574
0
            c3[0] = static_cast<charT>(i);
575
0
            string_type s3 = this->m_traits.transform(c3, c3 +1);
576
0
            if((s1 <= s3) && (s3 <= s2))
577
0
               result->_map[i] = true;
578
0
         }
579
0
      }
580
5
      else
581
5
      {
582
5
         if(char_less(c2, c1))
583
0
         {
584
            // Oops error:
585
0
            return 0;
586
0
         }
587
         // everything in range matches:
588
5
         std::memset(result->_map + static_cast<unsigned char>(c1), true, static_cast<unsigned char>(1u) + static_cast<unsigned char>(static_cast<unsigned char>(c2) - static_cast<unsigned char>(c1)));
589
5
      }
590
5
   }
591
   //
592
   // and now the classes:
593
   //
594
5
   typedef typename traits::char_class_type m_type;
595
5
   m_type m = char_set.classes();
596
5
   if(flags() & regbase::icase)
597
0
   {
598
      // adjust m as needed:
599
0
      if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))
600
0
         m |= m_alpha_mask;
601
0
   }
602
5
   if(m != 0)
603
0
   {
604
0
      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
605
0
      {
606
0
         if(this->m_traits.isctype(static_cast<charT>(i), m))
607
0
            result->_map[i] = true;
608
0
      }
609
0
   }
610
   //
611
   // and now the negated classes:
612
   //
613
5
   m = char_set.negated_classes();
614
5
   if(flags() & regbase::icase)
615
0
   {
616
      // adjust m as needed:
617
0
      if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))
618
0
         m |= m_alpha_mask;
619
0
   }
620
5
   if(m != 0)
621
0
   {
622
0
      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
623
0
      {
624
0
         if(0 == this->m_traits.isctype(static_cast<charT>(i), m))
625
0
            result->_map[i] = true;
626
0
      }
627
0
   }
628
   //
629
   // now process the equivalence classes:
630
   //
631
5
   sfirst = char_set.equivalents_begin();
632
5
   slast = char_set.equivalents_end();
633
5
   while(sfirst != slast)
634
0
   {
635
0
      string_type s;
636
0
      BOOST_REGEX_ASSERT(static_cast<charT>(0) == sfirst->second);
637
0
      s = m_traits.transform_primary(&sfirst->first, &sfirst->first+1);
638
0
      if(s.empty())
639
0
         return 0;  // invalid or unsupported equivalence class
640
0
      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
641
0
      {
642
0
         charT c[2] = { (static_cast<charT>(i)), charT(0), };
643
0
         string_type s2 = this->m_traits.transform_primary(c, c+1);
644
0
         if(s == s2)
645
0
            result->_map[i] = true;
646
0
      }
647
0
      ++sfirst;
648
0
   }
649
5
   if(negate)
650
0
   {
651
0
      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
652
0
      {
653
0
         result->_map[i] = !(result->_map[i]);
654
0
      }
655
0
   }
656
5
   return result;
657
5
}
658
659
template <class charT, class traits>
660
void basic_regex_creator<charT, traits>::finalize(const charT* p1, const charT* p2)
661
5
{
662
5
   if(this->m_pdata->m_status)
663
0
      return;
664
   // we've added all the states we need, now finish things off.
665
   // start by adding a terminating state:
666
5
   append_state(syntax_element_match);
667
   // extend storage to store original expression:
668
5
   std::ptrdiff_t len = p2 - p1;
669
5
   m_pdata->m_expression_len = len;
670
5
   charT* ps = static_cast<charT*>(m_pdata->m_data.extend(sizeof(charT) * (1 + (p2 - p1))));
671
5
   m_pdata->m_expression = ps;
672
5
   BOOST_REGEX_DETAIL_NS::copy(p1, p2, ps);
673
5
   ps[p2 - p1] = 0;
674
   // fill in our other data...
675
   // successful parsing implies a zero status:
676
5
   m_pdata->m_status = 0;
677
   // get the first state of the machine:
678
5
   m_pdata->m_first_state = static_cast<re_syntax_base*>(m_pdata->m_data.data());
679
   // fixup pointers in the machine:
680
5
   fixup_pointers(m_pdata->m_first_state);
681
5
   if(m_has_recursions)
682
0
   {
683
0
      m_pdata->m_has_recursions = true;
684
0
      fixup_recursions(m_pdata->m_first_state);
685
0
      if(this->m_pdata->m_status)
686
0
         return;
687
0
   }
688
5
   else
689
5
      m_pdata->m_has_recursions = false;
690
   // create nested startmaps:
691
5
   create_startmaps(m_pdata->m_first_state);
692
   // create main startmap:
693
5
   std::memset(m_pdata->m_startmap, 0, sizeof(m_pdata->m_startmap));
694
5
   m_pdata->m_can_be_null = 0;
695
696
5
   m_bad_repeats = 0;
697
5
   if(m_has_recursions)
698
0
      m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);
699
5
   create_startmap(m_pdata->m_first_state, m_pdata->m_startmap, &(m_pdata->m_can_be_null), mask_all);
700
   // get the restart type:
701
5
   m_pdata->m_restart_type = get_restart_type(m_pdata->m_first_state);
702
   // optimise a leading repeat if there is one:
703
5
   probe_leading_repeat(m_pdata->m_first_state);
704
5
}
705
706
template <class charT, class traits>
707
void basic_regex_creator<charT, traits>::fixup_pointers(re_syntax_base* state)
708
5
{
709
75
   while(state)
710
70
   {
711
70
      switch(state->type)
712
70
      {
713
0
      case syntax_element_recurse:
714
0
         m_has_recursions = true;
715
0
         if(state->next.i)
716
0
            state->next.p = getaddress(state->next.i, state);
717
0
         else
718
0
            state->next.p = 0;
719
0
         break;
720
10
      case syntax_element_rep:
721
10
      case syntax_element_dot_rep:
722
10
      case syntax_element_char_rep:
723
10
      case syntax_element_short_set_rep:
724
10
      case syntax_element_long_set_rep:
725
         // set the state_id of this repeat:
726
10
         static_cast<re_repeat*>(state)->state_id = m_repeater_id++;
727
10
         BOOST_REGEX_FALLTHROUGH;
728
10
      case syntax_element_alt:
729
10
         std::memset(static_cast<re_alt*>(state)->_map, 0, sizeof(static_cast<re_alt*>(state)->_map));
730
10
         static_cast<re_alt*>(state)->can_be_null = 0;
731
10
         BOOST_REGEX_FALLTHROUGH;
732
20
      case syntax_element_jump:
733
20
         static_cast<re_jump*>(state)->alt.p = getaddress(static_cast<re_jump*>(state)->alt.i, state);
734
20
         BOOST_REGEX_FALLTHROUGH;
735
70
      default:
736
70
         if(state->next.i)
737
65
            state->next.p = getaddress(state->next.i, state);
738
5
         else
739
5
            state->next.p = 0;
740
70
      }
741
70
      state = state->next.p;
742
70
   }
743
5
}
744
745
template <class charT, class traits>
746
void basic_regex_creator<charT, traits>::fixup_recursions(re_syntax_base* state)
747
0
{
748
0
   re_syntax_base* base = state;
749
0
   while(state)
750
0
   {
751
0
      switch(state->type)
752
0
      {
753
0
      case syntax_element_assert_backref:
754
0
         {
755
            // just check that the index is valid:
756
0
            int idx = static_cast<const re_brace*>(state)->index;
757
0
            if(idx < 0)
758
0
            {
759
0
               idx = -idx-1;
760
0
               if(idx >= hash_value_mask)
761
0
               {
762
0
                  idx = m_pdata->get_id(idx);
763
0
                  if(idx <= 0)
764
0
                  {
765
                     // check of sub-expression that doesn't exist:
766
0
                     if(0 == this->m_pdata->m_status) // update the error code if not already set
767
0
                        this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;
768
                     //
769
                     // clear the expression, we should be empty:
770
                     //
771
0
                     this->m_pdata->m_expression = 0;
772
0
                     this->m_pdata->m_expression_len = 0;
773
                     //
774
                     // and throw if required:
775
                     //
776
0
                     if(0 == (this->flags() & regex_constants::no_except))
777
0
                     {
778
0
                        std::string message = "Encountered a forward reference to a marked sub-expression that does not exist.";
779
0
                        boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);
780
0
                        e.raise();
781
0
                     }
782
0
                  }
783
0
               }
784
0
            }
785
0
         }
786
0
         break;
787
0
      case syntax_element_recurse:
788
0
         {
789
0
            bool ok = false;
790
0
            re_syntax_base* p = base;
791
0
            std::ptrdiff_t idx = static_cast<re_jump*>(state)->alt.i;
792
0
            if(idx >= hash_value_mask)
793
0
            {
794
               //
795
               // There may be more than one capture group with this hash, just do what Perl
796
               // does and recurse to the leftmost:
797
               //
798
0
               idx = m_pdata->get_id(static_cast<int>(idx));
799
0
            }
800
0
            if(idx < 0)
801
0
            {
802
0
               ok = false;
803
0
            }
804
0
            else
805
0
            {
806
0
               while(p)
807
0
               {
808
0
                  if((p->type == syntax_element_startmark) && (static_cast<re_brace*>(p)->index == idx))
809
0
                  {
810
                     //
811
                     // We've found the target of the recursion, set the jump target:
812
                     //
813
0
                     static_cast<re_jump*>(state)->alt.p = p;
814
0
                     ok = true;
815
                     // 
816
                     // Now scan the target for nested repeats:
817
                     //
818
0
                     p = p->next.p;
819
0
                     int next_rep_id = 0;
820
0
                     while(p)
821
0
                     {
822
0
                        switch(p->type)
823
0
                        {
824
0
                        case syntax_element_rep:
825
0
                        case syntax_element_dot_rep:
826
0
                        case syntax_element_char_rep:
827
0
                        case syntax_element_short_set_rep:
828
0
                        case syntax_element_long_set_rep:
829
0
                           next_rep_id = static_cast<re_repeat*>(p)->state_id;
830
0
                           break;
831
0
                        case syntax_element_endmark:
832
0
                           if(static_cast<const re_brace*>(p)->index == idx)
833
0
                              next_rep_id = -1;
834
0
                           break;
835
0
                        default:
836
0
                           break;
837
0
                        }
838
0
                        if(next_rep_id)
839
0
                           break;
840
0
                        p = p->next.p;
841
0
                     }
842
0
                     if(next_rep_id > 0)
843
0
                     {
844
0
                        static_cast<re_recurse*>(state)->state_id = next_rep_id - 1;
845
0
                     }
846
847
0
                     break;
848
0
                  }
849
0
                  p = p->next.p;
850
0
               }
851
0
            }
852
0
            if(!ok)
853
0
            {
854
               // recursion to sub-expression that doesn't exist:
855
0
               if(0 == this->m_pdata->m_status) // update the error code if not already set
856
0
                  this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;
857
               //
858
               // clear the expression, we should be empty:
859
               //
860
0
               this->m_pdata->m_expression = 0;
861
0
               this->m_pdata->m_expression_len = 0;
862
               //
863
               // and throw if required:
864
               //
865
0
               if(0 == (this->flags() & regex_constants::no_except))
866
0
               {
867
0
                  std::string message = "Encountered a forward reference to a recursive sub-expression that does not exist.";
868
0
                  boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);
869
0
                  e.raise();
870
0
               }
871
0
            }
872
0
         }
873
0
         break;
874
0
      default:
875
0
         break;
876
0
      }
877
0
      state = state->next.p;
878
0
   }
879
0
}
880
881
template <class charT, class traits>
882
void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
883
5
{
884
   // non-recursive implementation:
885
   // create the last map in the machine first, so that earlier maps
886
   // can make use of the result...
887
   //
888
   // This was originally a recursive implementation, but that caused stack
889
   // overflows with complex expressions on small stacks (think COM+).
890
891
   // start by saving the case setting:
892
5
   bool l_icase = m_icase;
893
5
   std::vector<std::pair<bool, re_syntax_base*> > v;
894
895
75
   while(state)
896
70
   {
897
70
      switch(state->type)
898
70
      {
899
0
      case syntax_element_toggle_case:
900
         // we need to track case changes here:
901
0
         m_icase = static_cast<re_case*>(state)->icase;
902
0
         state = state->next.p;
903
0
         continue;
904
0
      case syntax_element_alt:
905
10
      case syntax_element_rep:
906
10
      case syntax_element_dot_rep:
907
10
      case syntax_element_char_rep:
908
10
      case syntax_element_short_set_rep:
909
10
      case syntax_element_long_set_rep:
910
         // just push the state onto our stack for now:
911
10
         v.push_back(std::pair<bool, re_syntax_base*>(m_icase, state));
912
10
         state = state->next.p;
913
10
         break;
914
0
      case syntax_element_backstep:
915
         // we need to calculate how big the backstep is:
916
0
         static_cast<re_brace*>(state)->index
917
0
            = this->calculate_backstep(state->next.p);
918
0
         if(static_cast<re_brace*>(state)->index < 0)
919
0
         {
920
            // Oops error:
921
0
            if(0 == this->m_pdata->m_status) // update the error code if not already set
922
0
               this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;
923
            //
924
            // clear the expression, we should be empty:
925
            //
926
0
            this->m_pdata->m_expression = 0;
927
0
            this->m_pdata->m_expression_len = 0;
928
            //
929
            // and throw if required:
930
            //
931
0
            if(0 == (this->flags() & regex_constants::no_except))
932
0
            {
933
0
               std::string message = "Invalid lookbehind assertion encountered in the regular expression.";
934
0
               boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);
935
0
               e.raise();
936
0
            }
937
0
         }
938
0
         BOOST_REGEX_FALLTHROUGH;
939
60
      default:
940
60
         state = state->next.p;
941
70
      }
942
70
   }
943
944
   // now work through our list, building all the maps as we go:
945
15
   while(!v.empty())
946
10
   {
947
      // Initialize m_recursion_checks if we need it:
948
10
      if(m_has_recursions)
949
0
         m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);
950
951
10
      const std::pair<bool, re_syntax_base*>& p = v.back();
952
10
      m_icase = p.first;
953
10
      state = p.second;
954
10
      v.pop_back();
955
956
      // Build maps:
957
10
      m_bad_repeats = 0;
958
10
      create_startmap(state->next.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_take);
959
10
      m_bad_repeats = 0;
960
961
10
      if(m_has_recursions)
962
0
         m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);
963
10
      create_startmap(static_cast<re_alt*>(state)->alt.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_skip);
964
      // adjust the type of the state to allow for faster matching:
965
10
      state->type = this->get_repeat_type(state);
966
10
   }
967
   // restore case sensitivity:
968
5
   m_icase = l_icase;
969
5
}
970
971
template <class charT, class traits>
972
int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)
973
0
{
974
0
   typedef typename traits::char_class_type m_type;
975
0
   int result = 0;
976
0
   while(state)
977
0
   {
978
0
      switch(state->type)
979
0
      {
980
0
      case syntax_element_startmark:
981
0
         if((static_cast<re_brace*>(state)->index == -1)
982
0
            || (static_cast<re_brace*>(state)->index == -2))
983
0
         {
984
0
            state = static_cast<re_jump*>(state->next.p)->alt.p->next.p;
985
0
            continue;
986
0
         }
987
0
         else if(static_cast<re_brace*>(state)->index == -3)
988
0
         {
989
0
            state = state->next.p->next.p;
990
0
            continue;
991
0
         }
992
0
         break;
993
0
      case syntax_element_endmark:
994
0
         if((static_cast<re_brace*>(state)->index == -1)
995
0
            || (static_cast<re_brace*>(state)->index == -2))
996
0
            return result;
997
0
         break;
998
0
      case syntax_element_literal:
999
0
         result += static_cast<re_literal*>(state)->length;
1000
0
         break;
1001
0
      case syntax_element_wild:
1002
0
      case syntax_element_set:
1003
0
         result += 1;
1004
0
         break;
1005
0
      case syntax_element_dot_rep:
1006
0
      case syntax_element_char_rep:
1007
0
      case syntax_element_short_set_rep:
1008
0
      case syntax_element_backref:
1009
0
      case syntax_element_rep:
1010
0
      case syntax_element_combining:
1011
0
      case syntax_element_long_set_rep:
1012
0
      case syntax_element_backstep:
1013
0
         {
1014
0
            re_repeat* rep = static_cast<re_repeat *>(state);
1015
            // adjust the type of the state to allow for faster matching:
1016
0
            state->type = this->get_repeat_type(state);
1017
0
            if((state->type == syntax_element_dot_rep) 
1018
0
               || (state->type == syntax_element_char_rep)
1019
0
               || (state->type == syntax_element_short_set_rep))
1020
0
            {
1021
0
               if(rep->max != rep->min)
1022
0
                  return -1;
1023
0
               result += static_cast<int>(rep->min);
1024
0
               state = rep->alt.p;
1025
0
               continue;
1026
0
            }
1027
0
            else if(state->type == syntax_element_long_set_rep)
1028
0
            {
1029
0
               BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_long_set);
1030
0
               if(static_cast<re_set_long<m_type>*>(rep->next.p)->singleton == 0)
1031
0
                  return -1;
1032
0
               if(rep->max != rep->min)
1033
0
                  return -1;
1034
0
               result += static_cast<int>(rep->min);
1035
0
               state = rep->alt.p;
1036
0
               continue;
1037
0
            }
1038
0
         }
1039
0
         return -1;
1040
0
      case syntax_element_long_set:
1041
0
         if(static_cast<re_set_long<m_type>*>(state)->singleton == 0)
1042
0
            return -1;
1043
0
         result += 1;
1044
0
         break;
1045
0
      case syntax_element_jump:
1046
0
         state = static_cast<re_jump*>(state)->alt.p;
1047
0
         continue;
1048
0
      case syntax_element_alt:
1049
0
         {
1050
0
            int r1 = calculate_backstep(state->next.p);
1051
0
            int r2 = calculate_backstep(static_cast<re_alt*>(state)->alt.p);
1052
0
            if((r1 < 0) || (r1 != r2))
1053
0
               return -1;
1054
0
            return result + r1;
1055
0
         }
1056
0
      default:
1057
0
         break;
1058
0
      }
1059
0
      state = state->next.p;
1060
0
   }
1061
0
   return -1;
1062
0
}
1063
1064
struct recursion_saver
1065
{
1066
   std::vector<unsigned char> saved_state;
1067
   std::vector<unsigned char>* state;
1068
30
   recursion_saver(std::vector<unsigned char>* p) : saved_state(*p), state(p) {}
1069
   ~recursion_saver()
1070
30
   {
1071
30
      state->swap(saved_state);
1072
30
   }
1073
};
1074
1075
template <class charT, class traits>
1076
void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask)
1077
30
{
1078
30
   recursion_saver saved_recursions(&m_recursion_checks);
1079
30
   int not_last_jump = 1;
1080
30
   re_syntax_base* recursion_start = 0;
1081
30
   int recursion_sub = 0;
1082
30
   re_syntax_base* recursion_restart = 0;
1083
1084
   // track case sensitivity:
1085
30
   bool l_icase = m_icase;
1086
1087
45
   while(state)
1088
45
   {
1089
45
      switch(state->type)
1090
45
      {
1091
0
      case syntax_element_toggle_case:
1092
0
         l_icase = static_cast<re_case*>(state)->icase;
1093
0
         state = state->next.p;
1094
0
         break;
1095
15
      case syntax_element_literal:
1096
15
      {
1097
         // don't set anything in *pnull, set each element in l_map
1098
         // that could match the first character in the literal:
1099
15
         if(l_map)
1100
15
         {
1101
15
            l_map[0] |= mask_init;
1102
15
            charT first_char = *static_cast<charT*>(static_cast<void*>(static_cast<re_literal*>(state) + 1));
1103
3.85k
            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
1104
3.84k
            {
1105
3.84k
               if(m_traits.translate(static_cast<charT>(i), l_icase) == first_char)
1106
15
                  l_map[i] |= mask;
1107
3.84k
            }
1108
15
         }
1109
15
         return;
1110
0
      }
1111
5
      case syntax_element_end_line:
1112
5
      {
1113
         // next character must be a line separator (if there is one):
1114
5
         if(l_map)
1115
5
         {
1116
5
            l_map[0] |= mask_init;
1117
5
            l_map[static_cast<unsigned>('\n')] |= mask;
1118
5
            l_map[static_cast<unsigned>('\r')] |= mask;
1119
5
            l_map[static_cast<unsigned>('\f')] |= mask;
1120
5
            l_map[0x85] |= mask;
1121
5
         }
1122
         // now figure out if we can match a NULL string at this point:
1123
5
         if(pnull)
1124
5
            create_startmap(state->next.p, 0, pnull, mask);
1125
5
         return;
1126
0
      }
1127
0
      case syntax_element_recurse:
1128
0
         {
1129
0
            BOOST_REGEX_ASSERT(static_cast<const re_jump*>(state)->alt.p->type == syntax_element_startmark);
1130
0
            recursion_sub = static_cast<re_brace*>(static_cast<const re_jump*>(state)->alt.p)->index;
1131
0
            if(m_recursion_checks[recursion_sub] & 1u)
1132
0
            {
1133
               // Infinite recursion!!
1134
0
               if(0 == this->m_pdata->m_status) // update the error code if not already set
1135
0
                  this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;
1136
               //
1137
               // clear the expression, we should be empty:
1138
               //
1139
0
               this->m_pdata->m_expression = 0;
1140
0
               this->m_pdata->m_expression_len = 0;
1141
               //
1142
               // and throw if required:
1143
               //
1144
0
               if(0 == (this->flags() & regex_constants::no_except))
1145
0
               {
1146
0
                  std::string message = "Encountered an infinite recursion.";
1147
0
                  boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);
1148
0
                  e.raise();
1149
0
               }
1150
0
            }
1151
0
            else if(recursion_start == 0)
1152
0
            {
1153
0
               recursion_start = state;
1154
0
               recursion_restart = state->next.p;
1155
0
               state = static_cast<re_jump*>(state)->alt.p;
1156
0
               m_recursion_checks[recursion_sub] |= 1u;
1157
0
               break;
1158
0
            }
1159
0
            m_recursion_checks[recursion_sub] |= 1u;
1160
            // can't handle nested recursion here...
1161
0
            BOOST_REGEX_FALLTHROUGH;
1162
0
         }
1163
0
      case syntax_element_backref:
1164
         // can be null, and any character can match:
1165
0
         if(pnull)
1166
0
            *pnull |= mask;
1167
0
         BOOST_REGEX_FALLTHROUGH;
1168
0
      case syntax_element_wild:
1169
0
      {
1170
         // can't be null, any character can match:
1171
0
         set_all_masks(l_map, mask);
1172
0
         return;
1173
0
      }
1174
0
      case syntax_element_accept:
1175
5
      case syntax_element_match:
1176
5
      {
1177
         // must be null, any character can match:
1178
5
         set_all_masks(l_map, mask);
1179
5
         if(pnull)
1180
5
            *pnull |= mask;
1181
5
         return;
1182
0
      }
1183
0
      case syntax_element_word_start:
1184
0
      {
1185
         // recurse, then AND with all the word characters:
1186
0
         create_startmap(state->next.p, l_map, pnull, mask);
1187
0
         if(l_map)
1188
0
         {
1189
0
            l_map[0] |= mask_init;
1190
0
            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
1191
0
            {
1192
0
               if(!m_traits.isctype(static_cast<charT>(i), m_word_mask))
1193
0
                  l_map[i] &= static_cast<unsigned char>(~mask);
1194
0
            }
1195
0
         }
1196
0
         return;
1197
0
      }
1198
0
      case syntax_element_word_end:
1199
0
      {
1200
         // recurse, then AND with all the word characters:
1201
0
         create_startmap(state->next.p, l_map, pnull, mask);
1202
0
         if(l_map)
1203
0
         {
1204
0
            l_map[0] |= mask_init;
1205
0
            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
1206
0
            {
1207
0
               if(m_traits.isctype(static_cast<charT>(i), m_word_mask))
1208
0
                  l_map[i] &= static_cast<unsigned char>(~mask);
1209
0
            }
1210
0
         }
1211
0
         return;
1212
0
      }
1213
0
      case syntax_element_buffer_end:
1214
0
      {
1215
         // we *must be null* :
1216
0
         if(pnull)
1217
0
            *pnull |= mask;
1218
0
         return;
1219
0
      }
1220
0
      case syntax_element_long_set:
1221
0
         if(l_map)
1222
0
         {
1223
0
            typedef typename traits::char_class_type m_type;
1224
0
            if(static_cast<re_set_long<m_type>*>(state)->singleton)
1225
0
            {
1226
0
               l_map[0] |= mask_init;
1227
0
               for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
1228
0
               {
1229
0
                  charT c = static_cast<charT>(i);
1230
0
                  if(&c != re_is_set_member(&c, &c + 1, static_cast<re_set_long<m_type>*>(state), *m_pdata, l_icase))
1231
0
                     l_map[i] |= mask;
1232
0
               }
1233
0
            }
1234
0
            else
1235
0
               set_all_masks(l_map, mask);
1236
0
         }
1237
0
         return;
1238
5
      case syntax_element_set:
1239
5
         if(l_map)
1240
5
         {
1241
5
            l_map[0] |= mask_init;
1242
1.28k
            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
1243
1.28k
            {
1244
1.28k
               if(static_cast<re_set*>(state)->_map[
1245
1.28k
                  static_cast<unsigned char>(m_traits.translate(static_cast<charT>(i), l_icase))])
1246
50
                  l_map[i] |= mask;
1247
1.28k
            }
1248
5
         }
1249
5
         return;
1250
0
      case syntax_element_jump:
1251
         // take the jump:
1252
0
         state = static_cast<re_alt*>(state)->alt.p;
1253
0
         not_last_jump = -1;
1254
0
         break;
1255
0
      case syntax_element_alt:
1256
0
      case syntax_element_rep:
1257
0
      case syntax_element_dot_rep:
1258
0
      case syntax_element_char_rep:
1259
0
      case syntax_element_short_set_rep:
1260
0
      case syntax_element_long_set_rep:
1261
0
         {
1262
0
            re_alt* rep = static_cast<re_alt*>(state);
1263
0
            if(rep->_map[0] & mask_init)
1264
0
            {
1265
0
               if(l_map)
1266
0
               {
1267
                  // copy previous results:
1268
0
                  l_map[0] |= mask_init;
1269
0
                  for(unsigned int i = 0; i <= UCHAR_MAX; ++i)
1270
0
                  {
1271
0
                     if(rep->_map[i] & mask_any)
1272
0
                        l_map[i] |= mask;
1273
0
                  }
1274
0
               }
1275
0
               if(pnull)
1276
0
               {
1277
0
                  if(rep->can_be_null & mask_any)
1278
0
                     *pnull |= mask;
1279
0
               }
1280
0
            }
1281
0
            else
1282
0
            {
1283
               // we haven't created a startmap for this alternative yet
1284
               // so take the union of the two options:
1285
0
               if(is_bad_repeat(state))
1286
0
               {
1287
0
                  set_all_masks(l_map, mask);
1288
0
                  if(pnull)
1289
0
                     *pnull |= mask;
1290
0
                  return;
1291
0
               }
1292
0
               set_bad_repeat(state);
1293
0
               create_startmap(state->next.p, l_map, pnull, mask);
1294
0
               if((state->type == syntax_element_alt)
1295
0
                  || (static_cast<re_repeat*>(state)->min == 0)
1296
0
                  || (not_last_jump == 0))
1297
0
                  create_startmap(rep->alt.p, l_map, pnull, mask);
1298
0
            }
1299
0
         }
1300
0
         return;
1301
0
      case syntax_element_soft_buffer_end:
1302
         // match newline or null:
1303
0
         if(l_map)
1304
0
         {
1305
0
            l_map[0] |= mask_init;
1306
0
            l_map[static_cast<unsigned>('\n')] |= mask;
1307
0
            l_map[static_cast<unsigned>('\r')] |= mask;
1308
0
         }
1309
0
         if(pnull)
1310
0
            *pnull |= mask;
1311
0
         return;
1312
0
      case syntax_element_endmark:
1313
         // need to handle independent subs as a special case:
1314
0
         if(static_cast<re_brace*>(state)->index < 0)
1315
0
         {
1316
            // can be null, any character can match:
1317
0
            set_all_masks(l_map, mask);
1318
0
            if(pnull)
1319
0
               *pnull |= mask;
1320
0
            return;
1321
0
         }
1322
0
         else if(recursion_start && (recursion_sub != 0) && (recursion_sub == static_cast<re_brace*>(state)->index))
1323
0
         {
1324
            // recursion termination:
1325
0
            recursion_start = 0;
1326
0
            state = recursion_restart;
1327
0
            break;
1328
0
         }
1329
1330
         //
1331
         // Normally we just go to the next state... but if this sub-expression is
1332
         // the target of a recursion, then we might be ending a recursion, in which
1333
         // case we should check whatever follows that recursion, as well as whatever
1334
         // follows this state:
1335
         //
1336
0
         if(m_pdata->m_has_recursions && static_cast<re_brace*>(state)->index)
1337
0
         {
1338
0
            bool ok = false;
1339
0
            re_syntax_base* p = m_pdata->m_first_state;
1340
0
            while(p)
1341
0
            {
1342
0
               if(p->type == syntax_element_recurse)
1343
0
               {
1344
0
                  re_brace* p2 = static_cast<re_brace*>(static_cast<re_jump*>(p)->alt.p);
1345
0
                  if((p2->type == syntax_element_startmark) && (p2->index == static_cast<re_brace*>(state)->index))
1346
0
                  {
1347
0
                     ok = true;
1348
0
                     break;
1349
0
                  }
1350
0
               }
1351
0
               p = p->next.p;
1352
0
            }
1353
0
            if(ok && ((m_recursion_checks[static_cast<re_brace*>(state)->index] & 2u) == 0))
1354
0
            {
1355
0
               m_recursion_checks[static_cast<re_brace*>(state)->index] |= 2u;
1356
0
               create_startmap(p->next.p, l_map, pnull, mask);
1357
0
            }
1358
0
         }
1359
0
         state = state->next.p;
1360
0
         break;
1361
1362
0
      case syntax_element_commit:
1363
0
         set_all_masks(l_map, mask);
1364
         // Continue scanning so we can figure out whether we can be null:
1365
0
         state = state->next.p;
1366
0
         break;
1367
10
      case syntax_element_startmark:
1368
         // need to handle independent subs as a special case:
1369
10
         if(static_cast<re_brace*>(state)->index == -3)
1370
0
         {
1371
0
            state = state->next.p->next.p;
1372
0
            break;
1373
0
         }
1374
10
         BOOST_REGEX_FALLTHROUGH;
1375
15
      default:
1376
15
         state = state->next.p;
1377
45
      }
1378
15
      ++not_last_jump;
1379
15
   }
1380
30
}
1381
1382
template <class charT, class traits>
1383
unsigned basic_regex_creator<charT, traits>::get_restart_type(re_syntax_base* state)
1384
5
{
1385
   //
1386
   // find out how the machine starts, so we can optimise the search:
1387
   //
1388
10
   while(state)
1389
10
   {
1390
10
      switch(state->type)
1391
10
      {
1392
5
      case syntax_element_startmark:
1393
5
      case syntax_element_endmark:
1394
5
         state = state->next.p;
1395
5
         continue;
1396
5
      case syntax_element_start_line:
1397
5
         return regbase::restart_line;
1398
0
      case syntax_element_word_start:
1399
0
         return regbase::restart_word;
1400
0
      case syntax_element_buffer_start:
1401
0
         return regbase::restart_buf;
1402
0
      case syntax_element_restart_continue:
1403
0
         return regbase::restart_continue;
1404
0
      default:
1405
0
         state = 0;
1406
0
         continue;
1407
10
      }
1408
10
   }
1409
0
   return regbase::restart_any;
1410
5
}
1411
1412
template <class charT, class traits>
1413
void basic_regex_creator<charT, traits>::set_all_masks(unsigned char* bits, unsigned char mask)
1414
5
{
1415
   //
1416
   // set mask in all of bits elements, 
1417
   // if bits[0] has mask_init not set then we can 
1418
   // optimise this to a call to memset:
1419
   //
1420
5
   if(bits)
1421
0
   {
1422
0
      if(bits[0] == 0)
1423
0
         (std::memset)(bits, mask, 1u << CHAR_BIT);
1424
0
      else
1425
0
      {
1426
0
         for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
1427
0
            bits[i] |= mask;
1428
0
      }
1429
0
      bits[0] |= mask_init;
1430
0
   }
1431
5
}
1432
1433
template <class charT, class traits>
1434
bool basic_regex_creator<charT, traits>::is_bad_repeat(re_syntax_base* pt)
1435
0
{
1436
0
   switch(pt->type)
1437
0
   {
1438
0
   case syntax_element_rep:
1439
0
   case syntax_element_dot_rep:
1440
0
   case syntax_element_char_rep:
1441
0
   case syntax_element_short_set_rep:
1442
0
   case syntax_element_long_set_rep:
1443
0
      {
1444
0
         unsigned state_id = static_cast<re_repeat*>(pt)->state_id;
1445
0
         if(state_id >= sizeof(m_bad_repeats) * CHAR_BIT)
1446
0
            return true;  // run out of bits, assume we can't traverse this one.
1447
0
         static const std::uintmax_t one = 1uL;
1448
0
         return m_bad_repeats & (one << state_id);
1449
0
      }
1450
0
   default:
1451
0
      return false;
1452
0
   }
1453
0
}
1454
1455
template <class charT, class traits>
1456
void basic_regex_creator<charT, traits>::set_bad_repeat(re_syntax_base* pt)
1457
0
{
1458
0
   switch(pt->type)
1459
0
   {
1460
0
   case syntax_element_rep:
1461
0
   case syntax_element_dot_rep:
1462
0
   case syntax_element_char_rep:
1463
0
   case syntax_element_short_set_rep:
1464
0
   case syntax_element_long_set_rep:
1465
0
      {
1466
0
         unsigned state_id = static_cast<re_repeat*>(pt)->state_id;
1467
0
         static const std::uintmax_t one = 1uL;
1468
0
         if(state_id <= sizeof(m_bad_repeats) * CHAR_BIT)
1469
0
            m_bad_repeats |= (one << state_id);
1470
0
      }
1471
0
      break;
1472
0
   default:
1473
0
      break;
1474
0
   }
1475
0
}
1476
1477
template <class charT, class traits>
1478
syntax_element_type basic_regex_creator<charT, traits>::get_repeat_type(re_syntax_base* state)
1479
10
{
1480
10
   typedef typename traits::char_class_type m_type;
1481
10
   if(state->type == syntax_element_rep)
1482
10
   {
1483
      // check to see if we are repeating a single state:
1484
10
      if(state->next.p->next.p->next.p == static_cast<re_alt*>(state)->alt.p)
1485
5
      {
1486
5
         switch(state->next.p->type)
1487
5
         {
1488
0
         case BOOST_REGEX_DETAIL_NS::syntax_element_wild:
1489
0
            return BOOST_REGEX_DETAIL_NS::syntax_element_dot_rep;
1490
0
         case BOOST_REGEX_DETAIL_NS::syntax_element_literal:
1491
0
            return BOOST_REGEX_DETAIL_NS::syntax_element_char_rep;
1492
5
         case BOOST_REGEX_DETAIL_NS::syntax_element_set:
1493
5
            return BOOST_REGEX_DETAIL_NS::syntax_element_short_set_rep;
1494
0
         case BOOST_REGEX_DETAIL_NS::syntax_element_long_set:
1495
0
            if(static_cast<BOOST_REGEX_DETAIL_NS::re_set_long<m_type>*>(state->next.p)->singleton)
1496
0
               return BOOST_REGEX_DETAIL_NS::syntax_element_long_set_rep;
1497
0
            break;
1498
0
         default:
1499
0
            break;
1500
5
         }
1501
5
      }
1502
10
   }
1503
5
   return state->type;
1504
10
}
1505
1506
template <class charT, class traits>
1507
void basic_regex_creator<charT, traits>::probe_leading_repeat(re_syntax_base* state)
1508
5
{
1509
   // enumerate our states, and see if we have a leading repeat 
1510
   // for which failed search restarts can be optimized;
1511
5
   do
1512
15
   {
1513
15
      switch(state->type)
1514
15
      {
1515
5
      case syntax_element_startmark:
1516
5
         if(static_cast<re_brace*>(state)->index >= 0)
1517
5
         {
1518
5
            state = state->next.p;
1519
5
            continue;
1520
5
         }
1521
#ifdef BOOST_REGEX_MSVC
1522
#  pragma warning(push)
1523
#pragma warning(disable:6011)
1524
#endif
1525
0
         if((static_cast<re_brace*>(state)->index == -1)
1526
0
            || (static_cast<re_brace*>(state)->index == -2))
1527
0
         {
1528
            // skip past the zero width assertion:
1529
0
            state = static_cast<const re_jump*>(state->next.p)->alt.p->next.p;
1530
0
            continue;
1531
0
         }
1532
#ifdef BOOST_REGEX_MSVC
1533
#  pragma warning(pop)
1534
#endif
1535
0
         if(static_cast<re_brace*>(state)->index == -3)
1536
0
         {
1537
            // Have to skip the leading jump state:
1538
0
            state = state->next.p->next.p;
1539
0
            continue;
1540
0
         }
1541
0
         return;
1542
0
      case syntax_element_endmark:
1543
5
      case syntax_element_start_line:
1544
5
      case syntax_element_end_line:
1545
5
      case syntax_element_word_boundary:
1546
5
      case syntax_element_within_word:
1547
5
      case syntax_element_word_start:
1548
5
      case syntax_element_word_end:
1549
5
      case syntax_element_buffer_start:
1550
5
      case syntax_element_buffer_end:
1551
5
      case syntax_element_restart_continue:
1552
5
         state = state->next.p;
1553
5
         break;
1554
0
      case syntax_element_dot_rep:
1555
0
      case syntax_element_char_rep:
1556
0
      case syntax_element_short_set_rep:
1557
0
      case syntax_element_long_set_rep:
1558
0
         if(this->m_has_backrefs == 0)
1559
0
            static_cast<re_repeat*>(state)->leading = true;
1560
0
         BOOST_REGEX_FALLTHROUGH;
1561
5
      default:
1562
5
         return;
1563
15
      }
1564
15
   }while(state);
1565
5
}
1566
1567
} // namespace BOOST_REGEX_DETAIL_NS
1568
1569
} // namespace boost
1570
1571
#ifdef BOOST_REGEX_MSVC
1572
#  pragma warning(pop)
1573
#endif
1574
1575
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/basic_regex_parser.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2004
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         basic_regex_parser.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares template class basic_regex_parser.
17
  */
18
19
#ifndef BOOST_REGEX_V5_BASIC_REGEX_PARSER_HPP
20
#define BOOST_REGEX_V5_BASIC_REGEX_PARSER_HPP
21
22
namespace boost{
23
namespace BOOST_REGEX_DETAIL_NS{
24
25
#ifdef BOOST_REGEX_MSVC
26
#pragma warning(push)
27
#pragma warning(disable:4244 4459)
28
#if BOOST_REGEX_MSVC < 1910
29
#pragma warning(disable:4800)
30
#endif
31
#endif
32
33
inline std::intmax_t umax(std::integral_constant<bool, false> const&)
34
0
{
35
   // Get out clause here, just in case numeric_limits is unspecialized:
36
0
   return std::numeric_limits<std::intmax_t>::is_specialized ? (std::numeric_limits<std::intmax_t>::max)() : INT_MAX;
37
0
}
38
inline std::intmax_t umax(std::integral_constant<bool, true> const&)
39
0
{
40
0
   return (std::numeric_limits<std::size_t>::max)();
41
0
}
42
43
inline std::intmax_t umax()
44
0
{
45
0
   return umax(std::integral_constant<bool, std::numeric_limits<std::intmax_t>::digits >= std::numeric_limits<std::size_t>::digits>());
46
0
}
47
48
template <class charT, class traits>
49
class basic_regex_parser : public basic_regex_creator<charT, traits>
50
{
51
public:
52
   basic_regex_parser(regex_data<charT, traits>* data);
53
   void parse(const charT* p1, const charT* p2, unsigned flags);
54
   void fail(regex_constants::error_type error_code, std::ptrdiff_t position);
55
   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos);
56
   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, const std::string& message)
57
0
   {
58
0
      fail(error_code, position, message, position);
59
0
   }
60
61
   bool parse_all();
62
   bool parse_basic();
63
   bool parse_extended();
64
   bool parse_literal();
65
   bool parse_open_paren();
66
   bool parse_basic_escape();
67
   bool parse_extended_escape();
68
   bool parse_match_any();
69
   bool parse_repeat(std::size_t low = 0, std::size_t high = (std::numeric_limits<std::size_t>::max)());
70
   bool parse_repeat_range(bool isbasic);
71
   bool parse_alt();
72
   bool parse_set();
73
   bool parse_backref();
74
   void parse_set_literal(basic_char_set<charT, traits>& char_set);
75
   bool parse_inner_set(basic_char_set<charT, traits>& char_set);
76
   bool parse_QE();
77
   bool parse_perl_extension();
78
   bool parse_perl_verb();
79
   bool match_verb(const char*);
80
   bool add_emacs_code(bool negate);
81
   bool unwind_alts(std::ptrdiff_t last_paren_start);
82
   digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set);
83
   charT unescape_character();
84
   regex_constants::syntax_option_type parse_options();
85
86
private:
87
   typedef bool (basic_regex_parser::*parser_proc_type)();
88
   typedef typename traits::string_type string_type;
89
   typedef typename traits::char_class_type char_class_type;
90
   parser_proc_type           m_parser_proc;    // the main parser to use
91
   const charT*               m_base;           // the start of the string being parsed
92
   const charT*               m_end;            // the end of the string being parsed
93
   const charT*               m_position;       // our current parser position
94
   unsigned                   m_mark_count;     // how many sub-expressions we have
95
   int                        m_mark_reset;     // used to indicate that we're inside a (?|...) block.
96
   unsigned                   m_max_mark;       // largest mark count seen inside a (?|...) block.
97
   std::ptrdiff_t             m_paren_start;    // where the last seen ')' began (where repeats are inserted).
98
   std::ptrdiff_t             m_alt_insert_point; // where to insert the next alternative
99
   bool                       m_has_case_change; // true if somewhere in the current block the case has changed
100
   unsigned                   m_recursion_count; // How many times we've called parse_all.
101
#if defined(BOOST_REGEX_MSVC) && defined(_M_IX86)
102
   // This is an ugly warning suppression workaround (for warnings *inside* std::vector
103
   // that can not otherwise be suppressed)...
104
   static_assert(sizeof(long) >= sizeof(void*), "Long isn't long enough!");
105
   std::vector<long>           m_alt_jumps;      // list of alternative in the current scope.
106
#else
107
   std::vector<std::ptrdiff_t> m_alt_jumps;      // list of alternative in the current scope.
108
#endif
109
110
   basic_regex_parser& operator=(const basic_regex_parser&);
111
   basic_regex_parser(const basic_regex_parser&);
112
};
113
114
template <class charT, class traits>
115
basic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)
116
   : basic_regex_creator<charT, traits>(data), m_parser_proc(), m_base(0), m_end(0), m_position(0), 
117
   m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false), m_recursion_count(0)
118
5
{
119
5
}
120
121
template <class charT, class traits>
122
void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2, unsigned l_flags)
123
5
{
124
   // pass l_flags on to base class:
125
5
   this->init(l_flags);
126
   // set up pointers:
127
5
   m_position = m_base = p1;
128
5
   m_end = p2;
129
   // empty strings are errors:
130
5
   if((p1 == p2) && 
131
5
      (
132
0
         ((l_flags & regbase::main_option_type) != regbase::perl_syntax_group)
133
0
         || (l_flags & regbase::no_empty_expressions)
134
0
      )
135
5
     )
136
0
   {
137
0
      fail(regex_constants::error_empty, 0);
138
0
      return;
139
0
   }
140
   // select which parser to use:
141
5
   switch(l_flags & regbase::main_option_type)
142
5
   {
143
5
   case regbase::perl_syntax_group:
144
5
      {
145
5
         m_parser_proc = &basic_regex_parser<charT, traits>::parse_extended;
146
         //
147
         // Add a leading paren with index zero to give recursions a target:
148
         //
149
5
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
150
5
         br->index = 0;
151
5
         br->icase = this->flags() & regbase::icase;
152
5
         break;
153
0
      }
154
0
   case regbase::basic_syntax_group:
155
0
      m_parser_proc = &basic_regex_parser<charT, traits>::parse_basic;
156
0
      break;
157
0
   case regbase::literal:
158
0
      m_parser_proc = &basic_regex_parser<charT, traits>::parse_literal;
159
0
      break;
160
0
   default:
161
      // Oops, someone has managed to set more than one of the main option flags, 
162
      // so this must be an error:
163
0
      fail(regex_constants::error_unknown, 0, "An invalid combination of regular expression syntax flags was used.");
164
0
      return;
165
5
   }
166
167
   // parse all our characters:
168
5
   bool result = parse_all();
169
   //
170
   // Unwind our alternatives:
171
   //
172
5
   unwind_alts(-1);
173
   // reset l_flags as a global scope (?imsx) may have altered them:
174
5
   this->flags(l_flags);
175
   // if we haven't gobbled up all the characters then we must
176
   // have had an unexpected ')' :
177
5
   if(!result)
178
0
   {
179
0
      fail(regex_constants::error_paren, std::distance(m_base, m_position), "Found a closing ) with no corresponding opening parenthesis.");
180
0
      return;
181
0
   }
182
   // if an error has been set then give up now:
183
5
   if(this->m_pdata->m_status)
184
0
      return;
185
   // fill in our sub-expression count:
186
5
   this->m_pdata->m_mark_count = 1u + (std::size_t)m_mark_count;
187
5
   this->finalize(p1, p2);
188
5
}
189
190
template <class charT, class traits>
191
void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position)
192
0
{
193
   // get the error message:
194
0
   std::string message = this->m_pdata->m_ptraits->error_string(error_code);
195
0
   fail(error_code, position, message);
196
0
}
197
198
template <class charT, class traits>
199
void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos)
200
0
{
201
0
   if(0 == this->m_pdata->m_status) // update the error code if not already set
202
0
      this->m_pdata->m_status = error_code;
203
0
   m_position = m_end; // don't bother parsing anything else
204
205
   //
206
   // Augment error message with the regular expression text:
207
   //
208
0
   if(start_pos == position)
209
0
      start_pos = (std::max)(static_cast<std::ptrdiff_t>(0), position - static_cast<std::ptrdiff_t>(10));
210
0
   std::ptrdiff_t end_pos = (std::min)(position + static_cast<std::ptrdiff_t>(10), static_cast<std::ptrdiff_t>(m_end - m_base));
211
0
   if(error_code != regex_constants::error_empty)
212
0
   {
213
0
      if((start_pos != 0) || (end_pos != (m_end - m_base)))
214
0
         message += "  The error occurred while parsing the regular expression fragment: '";
215
0
      else
216
0
         message += "  The error occurred while parsing the regular expression: '";
217
0
      if(start_pos != end_pos)
218
0
      {
219
0
         message += std::string(m_base + start_pos, m_base + position);
220
0
         message += ">>>HERE>>>";
221
0
         message += std::string(m_base + position, m_base + end_pos);
222
0
      }
223
0
      message += "'.";
224
0
   }
225
226
0
#ifndef BOOST_NO_EXCEPTIONS
227
0
   if(0 == (this->flags() & regex_constants::no_except))
228
0
   {
229
0
      boost::regex_error e(message, error_code, position);
230
0
      e.raise();
231
0
   }
232
#else
233
   (void)position; // suppress warnings.
234
#endif
235
0
}
236
237
template <class charT, class traits>
238
bool basic_regex_parser<charT, traits>::parse_all()
239
10
{
240
10
   if (++m_recursion_count > 400)
241
0
   {
242
      // exceeded internal limits
243
0
      fail(boost::regex_constants::error_complexity, m_position - m_base, "Exceeded nested brace limit.");
244
0
   }
245
10
   bool result = true;
246
60
   while(result && (m_position != m_end))
247
50
   {
248
50
      result = (this->*m_parser_proc)();
249
50
   }
250
10
   --m_recursion_count;
251
10
   return result;
252
10
}
253
254
#ifdef BOOST_REGEX_MSVC
255
#pragma warning(push)
256
#pragma warning(disable:4702)
257
#endif
258
template <class charT, class traits>
259
bool basic_regex_parser<charT, traits>::parse_basic()
260
0
{
261
0
   switch(this->m_traits.syntax_type(*m_position))
262
0
   {
263
0
   case regex_constants::syntax_escape:
264
0
      return parse_basic_escape();
265
0
   case regex_constants::syntax_dot:
266
0
      return parse_match_any();
267
0
   case regex_constants::syntax_caret:
268
0
      ++m_position;
269
0
      this->append_state(syntax_element_start_line);
270
0
      break;
271
0
   case regex_constants::syntax_dollar:
272
0
      ++m_position;
273
0
      this->append_state(syntax_element_end_line);
274
0
      break;
275
0
   case regex_constants::syntax_star:
276
0
      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line))
277
0
         return parse_literal();
278
0
      else
279
0
      {
280
0
         ++m_position;
281
0
         return parse_repeat();
282
0
      }
283
0
   case regex_constants::syntax_plus:
284
0
      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
285
0
         return parse_literal();
286
0
      else
287
0
      {
288
0
         ++m_position;
289
0
         return parse_repeat(1);
290
0
      }
291
0
   case regex_constants::syntax_question:
292
0
      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
293
0
         return parse_literal();
294
0
      else
295
0
      {
296
0
         ++m_position;
297
0
         return parse_repeat(0, 1);
298
0
      }
299
0
   case regex_constants::syntax_open_set:
300
0
      return parse_set();
301
0
   case regex_constants::syntax_newline:
302
0
      if(this->flags() & regbase::newline_alt)
303
0
         return parse_alt();
304
0
      else
305
0
         return parse_literal();
306
0
   default:
307
0
      return parse_literal();
308
0
   }
309
0
   return true;
310
0
}
311
312
#ifdef BOOST_REGEX_MSVC
313
#  pragma warning(push)
314
#if BOOST_REGEX_MSVC >= 1800
315
#pragma warning(disable:26812)
316
#endif
317
#endif
318
template <class charT, class traits>
319
bool basic_regex_parser<charT, traits>::parse_extended()
320
50
{
321
50
   bool result = true;
322
50
   switch(this->m_traits.syntax_type(*m_position))
323
50
   {
324
5
   case regex_constants::syntax_open_mark:
325
5
      return parse_open_paren();
326
5
   case regex_constants::syntax_close_mark:
327
5
      return false;
328
5
   case regex_constants::syntax_escape:
329
5
      return parse_extended_escape();
330
0
   case regex_constants::syntax_dot:
331
0
      return parse_match_any();
332
5
   case regex_constants::syntax_caret:
333
5
      ++m_position;
334
5
      this->append_state(
335
5
         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_start : syntax_element_start_line));
336
5
      break;
337
5
   case regex_constants::syntax_dollar:
338
5
      ++m_position;
339
5
      this->append_state(
340
5
         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_end : syntax_element_end_line));
341
5
      break;
342
0
   case regex_constants::syntax_star:
343
0
      if(m_position == this->m_base)
344
0
      {
345
0
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"*\" cannot start a regular expression.");
346
0
         return false;
347
0
      }
348
0
      ++m_position;
349
0
      return parse_repeat();
350
0
   case regex_constants::syntax_question:
351
0
      if(m_position == this->m_base)
352
0
      {
353
0
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"?\" cannot start a regular expression.");
354
0
         return false;
355
0
      }
356
0
      ++m_position;
357
0
      return parse_repeat(0,1);
358
10
   case regex_constants::syntax_plus:
359
10
      if(m_position == this->m_base)
360
0
      {
361
0
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"+\" cannot start a regular expression.");
362
0
         return false;
363
0
      }
364
10
      ++m_position;
365
10
      return parse_repeat(1);
366
0
   case regex_constants::syntax_open_brace:
367
0
      ++m_position;
368
0
      return parse_repeat_range(false);
369
0
   case regex_constants::syntax_close_brace:
370
0
      if((this->flags() & regbase::no_perl_ex) == regbase::no_perl_ex)
371
0
      {
372
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, "Found a closing repetition operator } with no corresponding {.");
373
0
         return false;
374
0
      }
375
0
      result = parse_literal();
376
0
      break;
377
0
   case regex_constants::syntax_or:
378
0
      return parse_alt();
379
5
   case regex_constants::syntax_open_set:
380
5
      return parse_set();
381
0
   case regex_constants::syntax_newline:
382
0
      if(this->flags() & regbase::newline_alt)
383
0
         return parse_alt();
384
0
      else
385
0
         return parse_literal();
386
0
   case regex_constants::syntax_hash:
387
      //
388
      // If we have a mod_x flag set, then skip until
389
      // we get to a newline character:
390
      //
391
0
      if((this->flags() 
392
0
         & (regbase::no_perl_ex|regbase::mod_x))
393
0
         == regbase::mod_x)
394
0
      {
395
0
         while((m_position != m_end) && !is_separator(*m_position++)){}
396
0
         return true;
397
0
      }
398
0
      BOOST_REGEX_FALLTHROUGH;
399
10
   default:
400
10
      result = parse_literal();
401
10
      break;
402
50
   }
403
20
   return result;
404
50
}
405
#ifdef BOOST_REGEX_MSVC
406
#  pragma warning(pop)
407
#endif
408
#ifdef BOOST_REGEX_MSVC
409
#pragma warning(pop)
410
#endif
411
412
template <class charT, class traits>
413
bool basic_regex_parser<charT, traits>::parse_literal()
414
10
{
415
   // append this as a literal provided it's not a space character
416
   // or the perl option regbase::mod_x is not set:
417
10
   if(
418
10
      ((this->flags() 
419
10
         & (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex)) 
420
10
            != regbase::mod_x)
421
10
      || !this->m_traits.isctype(*m_position, this->m_mask_space))
422
10
         this->append_literal(*m_position);
423
10
   ++m_position;
424
10
   return true;
425
10
}
426
427
template <class charT, class traits>
428
bool basic_regex_parser<charT, traits>::parse_open_paren()
429
5
{
430
   //
431
   // skip the '(' and error check:
432
   //
433
5
   if(++m_position == m_end)
434
0
   {
435
0
      fail(regex_constants::error_paren, m_position - m_base);
436
0
      return false;
437
0
   }
438
   //
439
   // begin by checking for a perl-style (?...) extension:
440
   //
441
5
   if(
442
5
         ((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)
443
5
         || ((this->flags() & (regbase::main_option_type | regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
444
5
     )
445
5
   {
446
5
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
447
0
         return parse_perl_extension();
448
5
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_star)
449
0
         return parse_perl_verb();
450
5
   }
451
   //
452
   // update our mark count, and append the required state:
453
   //
454
5
   unsigned markid = 0;
455
5
   if(0 == (this->flags() & regbase::nosubs))
456
5
   {
457
5
      markid = ++m_mark_count;
458
5
      if(this->flags() & regbase::save_subexpression_location)
459
0
         this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 1, 0));
460
5
   }
461
5
   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
462
5
   pb->index = markid;
463
5
   pb->icase = this->flags() & regbase::icase;
464
5
   std::ptrdiff_t last_paren_start = this->getoffset(pb);
465
   // back up insertion point for alternations, and set new point:
466
5
   std::ptrdiff_t last_alt_point = m_alt_insert_point;
467
5
   this->m_pdata->m_data.align();
468
5
   m_alt_insert_point = this->m_pdata->m_data.size();
469
   //
470
   // back up the current flags in case we have a nested (?imsx) group:
471
   //
472
5
   regex_constants::syntax_option_type opts = this->flags();
473
5
   bool old_case_change = m_has_case_change;
474
5
   m_has_case_change = false; // no changes to this scope as yet...
475
   //
476
   // Back up branch reset data in case we have a nested (?|...)
477
   //
478
5
   int mark_reset = m_mark_reset;
479
5
   m_mark_reset = -1;
480
   //
481
   // now recursively add more states, this will terminate when we get to a
482
   // matching ')' :
483
   //
484
5
   parse_all();
485
   //
486
   // Unwind pushed alternatives:
487
   //
488
5
   if(0 == unwind_alts(last_paren_start))
489
0
      return false;
490
   //
491
   // restore flags:
492
   //
493
5
   if(m_has_case_change)
494
0
   {
495
      // the case has changed in one or more of the alternatives
496
      // within the scoped (...) block: we have to add a state
497
      // to reset the case sensitivity:
498
0
      static_cast<re_case*>(
499
0
         this->append_state(syntax_element_toggle_case, sizeof(re_case))
500
0
         )->icase = opts & regbase::icase;
501
0
   }
502
5
   this->flags(opts);
503
5
   m_has_case_change = old_case_change;
504
   //
505
   // restore branch reset:
506
   //
507
5
   m_mark_reset = mark_reset;
508
   //
509
   // we either have a ')' or we have run out of characters prematurely:
510
   //
511
5
   if(m_position == m_end)
512
0
   {
513
0
      this->fail(regex_constants::error_paren, std::distance(m_base, m_end));
514
0
      return false;
515
0
   }
516
5
   if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
517
0
      return false;
518
5
   if(markid && (this->flags() & regbase::save_subexpression_location))
519
0
      this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position);
520
5
   ++m_position;
521
   //
522
   // append closing parenthesis state:
523
   //
524
5
   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
525
5
   pb->index = markid;
526
5
   pb->icase = this->flags() & regbase::icase;
527
5
   this->m_paren_start = last_paren_start;
528
   //
529
   // restore the alternate insertion point:
530
   //
531
5
   this->m_alt_insert_point = last_alt_point;
532
   //
533
   // allow backrefs to this mark:
534
   //
535
5
   if(markid > 0)
536
5
      this->m_backrefs.set(markid);
537
538
5
   return true;
539
5
}
540
541
template <class charT, class traits>
542
bool basic_regex_parser<charT, traits>::parse_basic_escape()
543
0
{
544
0
   if(++m_position == m_end)
545
0
   {
546
0
      fail(regex_constants::error_paren, m_position - m_base);
547
0
      return false;
548
0
   }
549
0
   bool result = true;
550
0
   switch(this->m_traits.escape_syntax_type(*m_position))
551
0
   {
552
0
   case regex_constants::syntax_open_mark:
553
0
      return parse_open_paren();
554
0
   case regex_constants::syntax_close_mark:
555
0
      return false;
556
0
   case regex_constants::syntax_plus:
557
0
      if(this->flags() & regex_constants::bk_plus_qm)
558
0
      {
559
0
         ++m_position;
560
0
         return parse_repeat(1);
561
0
      }
562
0
      else
563
0
         return parse_literal();
564
0
   case regex_constants::syntax_question:
565
0
      if(this->flags() & regex_constants::bk_plus_qm)
566
0
      {
567
0
         ++m_position;
568
0
         return parse_repeat(0, 1);
569
0
      }
570
0
      else
571
0
         return parse_literal();
572
0
   case regex_constants::syntax_open_brace:
573
0
      if(this->flags() & regbase::no_intervals)
574
0
         return parse_literal();
575
0
      ++m_position;
576
0
      return parse_repeat_range(true);
577
0
   case regex_constants::syntax_close_brace:
578
0
      if(this->flags() & regbase::no_intervals)
579
0
         return parse_literal();
580
0
      fail(regex_constants::error_brace, this->m_position - this->m_base, "Found a closing repetition operator } with no corresponding {.");
581
0
      return false;
582
0
   case regex_constants::syntax_or:
583
0
      if(this->flags() & regbase::bk_vbar)
584
0
         return parse_alt();
585
0
      else
586
0
         result = parse_literal();
587
0
      break;
588
0
   case regex_constants::syntax_digit:
589
0
      return parse_backref();
590
0
   case regex_constants::escape_type_start_buffer:
591
0
      if(this->flags() & regbase::emacs_ex)
592
0
      {
593
0
         ++m_position;
594
0
         this->append_state(syntax_element_buffer_start);
595
0
      }
596
0
      else
597
0
         result = parse_literal();
598
0
      break;
599
0
   case regex_constants::escape_type_end_buffer:
600
0
      if(this->flags() & regbase::emacs_ex)
601
0
      {
602
0
         ++m_position;
603
0
         this->append_state(syntax_element_buffer_end);
604
0
      }
605
0
      else
606
0
         result = parse_literal();
607
0
      break;
608
0
   case regex_constants::escape_type_word_assert:
609
0
      if(this->flags() & regbase::emacs_ex)
610
0
      {
611
0
         ++m_position;
612
0
         this->append_state(syntax_element_word_boundary);
613
0
      }
614
0
      else
615
0
         result = parse_literal();
616
0
      break;
617
0
   case regex_constants::escape_type_not_word_assert:
618
0
      if(this->flags() & regbase::emacs_ex)
619
0
      {
620
0
         ++m_position;
621
0
         this->append_state(syntax_element_within_word);
622
0
      }
623
0
      else
624
0
         result = parse_literal();
625
0
      break;
626
0
   case regex_constants::escape_type_left_word:
627
0
      if(this->flags() & regbase::emacs_ex)
628
0
      {
629
0
         ++m_position;
630
0
         this->append_state(syntax_element_word_start);
631
0
      }
632
0
      else
633
0
         result = parse_literal();
634
0
      break;
635
0
   case regex_constants::escape_type_right_word:
636
0
      if(this->flags() & regbase::emacs_ex)
637
0
      {
638
0
         ++m_position;
639
0
         this->append_state(syntax_element_word_end);
640
0
      }
641
0
      else
642
0
         result = parse_literal();
643
0
      break;
644
0
   default:
645
0
      if(this->flags() & regbase::emacs_ex)
646
0
      {
647
0
         bool negate = true;
648
0
         switch(*m_position)
649
0
         {
650
0
         case 'w':
651
0
            negate = false;
652
0
            BOOST_REGEX_FALLTHROUGH;
653
0
         case 'W':
654
0
            {
655
0
            basic_char_set<charT, traits> char_set;
656
0
            if(negate)
657
0
               char_set.negate();
658
0
            char_set.add_class(this->m_word_mask);
659
0
            if(0 == this->append_set(char_set))
660
0
            {
661
0
               fail(regex_constants::error_ctype, m_position - m_base);
662
0
               return false;
663
0
            }
664
0
            ++m_position;
665
0
            return true;
666
0
            }
667
0
         case 's':
668
0
            negate = false;
669
0
            BOOST_REGEX_FALLTHROUGH;
670
0
         case 'S':
671
0
            return add_emacs_code(negate);
672
0
         case 'c':
673
0
         case 'C':
674
            // not supported yet:
675
0
            fail(regex_constants::error_escape, m_position - m_base, "The \\c and \\C escape sequences are not supported by POSIX basic regular expressions: try the Perl syntax instead.");
676
0
            return false;
677
0
         default:
678
0
            break;
679
0
         }
680
0
      }
681
0
      result = parse_literal();
682
0
      break;
683
0
   }
684
0
   return result;
685
0
}
686
687
template <class charT, class traits>
688
bool basic_regex_parser<charT, traits>::parse_extended_escape()
689
5
{
690
5
   ++m_position;
691
5
   if(m_position == m_end)
692
0
   {
693
0
      fail(regex_constants::error_escape, m_position - m_base, "Incomplete escape sequence found.");
694
0
      return false;
695
0
   }
696
5
   bool negate = false; // in case this is a character class escape: \w \d etc
697
5
   switch(this->m_traits.escape_syntax_type(*m_position))
698
5
   {
699
0
   case regex_constants::escape_type_not_class:
700
0
      negate = true;
701
0
      BOOST_REGEX_FALLTHROUGH;
702
0
   case regex_constants::escape_type_class:
703
0
      {
704
0
escape_type_class_jump:
705
0
         typedef typename traits::char_class_type m_type;
706
0
         m_type m = this->m_traits.lookup_classname(m_position, m_position+1);
707
0
         if(m != 0)
708
0
         {
709
0
            basic_char_set<charT, traits> char_set;
710
0
            if(negate)
711
0
               char_set.negate();
712
0
            char_set.add_class(m);
713
0
            if(0 == this->append_set(char_set))
714
0
            {
715
0
               fail(regex_constants::error_ctype, m_position - m_base);
716
0
               return false;
717
0
            }
718
0
            ++m_position;
719
0
            return true;
720
0
         }
721
         //
722
         // not a class, just a regular unknown escape:
723
         //
724
0
         this->append_literal(unescape_character());
725
0
         break;
726
0
      }
727
0
   case regex_constants::syntax_digit:
728
0
      return parse_backref();
729
0
   case regex_constants::escape_type_left_word:
730
0
      ++m_position;
731
0
      this->append_state(syntax_element_word_start);
732
0
      break;
733
0
   case regex_constants::escape_type_right_word:
734
0
      ++m_position;
735
0
      this->append_state(syntax_element_word_end);
736
0
      break;
737
0
   case regex_constants::escape_type_start_buffer:
738
0
      ++m_position;
739
0
      this->append_state(syntax_element_buffer_start);
740
0
      break;
741
0
   case regex_constants::escape_type_end_buffer:
742
0
      ++m_position;
743
0
      this->append_state(syntax_element_buffer_end);
744
0
      break;
745
0
   case regex_constants::escape_type_word_assert:
746
0
      ++m_position;
747
0
      this->append_state(syntax_element_word_boundary);
748
0
      break;
749
0
   case regex_constants::escape_type_not_word_assert:
750
0
      ++m_position;
751
0
      this->append_state(syntax_element_within_word);
752
0
      break;
753
0
   case regex_constants::escape_type_Z:
754
0
      ++m_position;
755
0
      this->append_state(syntax_element_soft_buffer_end);
756
0
      break;
757
0
   case regex_constants::escape_type_Q:
758
0
      return parse_QE();
759
0
   case regex_constants::escape_type_C:
760
0
      return parse_match_any();
761
0
   case regex_constants::escape_type_X:
762
0
      ++m_position;
763
0
      this->append_state(syntax_element_combining);
764
0
      break;
765
0
   case regex_constants::escape_type_G:
766
0
      ++m_position;
767
0
      this->append_state(syntax_element_restart_continue);
768
0
      break;
769
0
   case regex_constants::escape_type_not_property:
770
0
      negate = true;
771
0
      BOOST_REGEX_FALLTHROUGH;
772
0
   case regex_constants::escape_type_property:
773
0
      {
774
0
         ++m_position;
775
0
         char_class_type m;
776
0
         if(m_position == m_end)
777
0
         {
778
0
            fail(regex_constants::error_escape, m_position - m_base, "Incomplete property escape found.");
779
0
            return false;
780
0
         }
781
         // maybe have \p{ddd}
782
0
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
783
0
         {
784
0
            const charT* base = m_position;
785
            // skip forward until we find enclosing brace:
786
0
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
787
0
               ++m_position;
788
0
            if(m_position == m_end)
789
0
            {
790
0
               fail(regex_constants::error_escape, m_position - m_base, "Closing } missing from property escape sequence.");
791
0
               return false;
792
0
            }
793
0
            m = this->m_traits.lookup_classname(++base, m_position++);
794
0
         }
795
0
         else
796
0
         {
797
0
            m = this->m_traits.lookup_classname(m_position, m_position+1);
798
0
            ++m_position;
799
0
         }
800
0
         if(m != 0)
801
0
         {
802
0
            basic_char_set<charT, traits> char_set;
803
0
            if(negate)
804
0
               char_set.negate();
805
0
            char_set.add_class(m);
806
0
            if(0 == this->append_set(char_set))
807
0
            {
808
0
               fail(regex_constants::error_ctype, m_position - m_base);
809
0
               return false;
810
0
            }
811
0
            return true;
812
0
         }
813
0
         fail(regex_constants::error_ctype, m_position - m_base, "Escape sequence was neither a valid property nor a valid character class name.");
814
0
         return false;
815
0
      }
816
0
   case regex_constants::escape_type_reset_start_mark:
817
0
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
818
0
      {
819
0
         re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
820
0
         pb->index = -5;
821
0
         pb->icase = this->flags() & regbase::icase;
822
0
         this->m_pdata->m_data.align();
823
0
         ++m_position;
824
0
         return true;
825
0
      }
826
0
      goto escape_type_class_jump;
827
0
   case regex_constants::escape_type_line_ending:
828
0
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
829
0
      {
830
0
         const charT* e = get_escape_R_string<charT>();
831
0
         const charT* old_position = m_position;
832
0
         const charT* old_end = m_end;
833
0
         const charT* old_base = m_base;
834
0
         m_position = e;
835
0
         m_base = e;
836
0
         m_end = e + traits::length(e);
837
0
         bool r = parse_all();
838
0
         m_position = ++old_position;
839
0
         m_end = old_end;
840
0
         m_base = old_base;
841
0
         return r;
842
0
      }
843
0
      goto escape_type_class_jump;
844
0
   case regex_constants::escape_type_extended_backref:
845
0
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
846
0
      {
847
0
         bool have_brace = false;
848
0
         bool negative = false;
849
0
         static const char incomplete_message[] = "Incomplete \\g escape found.";
850
0
         if(++m_position == m_end)
851
0
         {
852
0
            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
853
0
            return false;
854
0
         }
855
         // maybe have \g{ddd}
856
0
         regex_constants::syntax_type syn = this->m_traits.syntax_type(*m_position);
857
0
         regex_constants::syntax_type syn_end = 0;
858
0
         if((syn == regex_constants::syntax_open_brace) 
859
0
            || (syn == regex_constants::escape_type_left_word)
860
0
            || (syn == regex_constants::escape_type_end_buffer))
861
0
         {
862
0
            if(++m_position == m_end)
863
0
            {
864
0
               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
865
0
               return false;
866
0
            }
867
0
            have_brace = true;
868
0
            switch(syn)
869
0
            {
870
0
            case regex_constants::syntax_open_brace:
871
0
               syn_end = regex_constants::syntax_close_brace;
872
0
               break;
873
0
            case regex_constants::escape_type_left_word:
874
0
               syn_end = regex_constants::escape_type_right_word;
875
0
               break;
876
0
            default:
877
0
               syn_end = regex_constants::escape_type_end_buffer;
878
0
               break;
879
0
            }
880
0
         }
881
0
         negative = (*m_position == static_cast<charT>('-'));
882
0
         if((negative) && (++m_position == m_end))
883
0
         {
884
0
            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
885
0
            return false;
886
0
         }
887
0
         const charT* pc = m_position;
888
0
         std::intmax_t i = this->m_traits.toi(pc, m_end, 10);
889
0
         if((i < 0) && syn_end)
890
0
         {
891
            // Check for a named capture, get the leftmost one if there is more than one:
892
0
            const charT* base = m_position;
893
0
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != syn_end))
894
0
            {
895
0
               ++m_position;
896
0
            }
897
0
            i = hash_value_from_capture_name(base, m_position);
898
0
            pc = m_position;
899
0
         }
900
0
         if(negative)
901
0
            i = 1 + (static_cast<std::intmax_t>(m_mark_count) - i);
902
0
         if(((i < hash_value_mask) && (i > 0) && (this->m_backrefs.test((std::size_t)i))) || ((i >= hash_value_mask) && (this->m_pdata->get_id((int)i) > 0) && (this->m_backrefs.test(this->m_pdata->get_id((int)i)))))
903
0
         {
904
0
            m_position = pc;
905
0
            re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
906
0
            pb->index = (int)i;
907
0
            pb->icase = this->flags() & regbase::icase;
908
0
         }
909
0
         else
910
0
         {
911
0
            fail(regex_constants::error_backref, m_position - m_base);
912
0
            return false;
913
0
         }
914
0
         m_position = pc;
915
0
         if(have_brace)
916
0
         {
917
0
            if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != syn_end))
918
0
            {
919
0
               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
920
0
               return false;
921
0
            }
922
0
            ++m_position;
923
0
         }
924
0
         return true;
925
0
      }
926
0
      goto escape_type_class_jump;
927
0
   case regex_constants::escape_type_control_v:
928
0
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
929
0
         goto escape_type_class_jump;
930
0
      BOOST_REGEX_FALLTHROUGH;
931
5
   default:
932
5
      this->append_literal(unescape_character());
933
5
      break;
934
5
   }
935
5
   return true;
936
5
}
937
938
template <class charT, class traits>
939
bool basic_regex_parser<charT, traits>::parse_match_any()
940
0
{
941
   //
942
   // we have a '.' that can match any character:
943
   //
944
0
   ++m_position;
945
0
   static_cast<re_dot*>(
946
0
      this->append_state(syntax_element_wild, sizeof(re_dot))
947
0
      )->mask = static_cast<unsigned char>(this->flags() & regbase::no_mod_s 
948
0
      ? BOOST_REGEX_DETAIL_NS::force_not_newline 
949
0
         : this->flags() & regbase::mod_s ?
950
0
            BOOST_REGEX_DETAIL_NS::force_newline : BOOST_REGEX_DETAIL_NS::dont_care);
951
0
   return true;
952
0
}
953
954
template <class charT, class traits>
955
bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_t high)
956
10
{
957
10
   bool greedy = true;
958
10
   bool possessive = false;
959
10
   std::size_t insert_point;
960
   // 
961
   // when we get to here we may have a non-greedy ? mark still to come:
962
   //
963
10
   if((m_position != m_end) 
964
10
      && (
965
10
            (0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
966
10
            || ((regbase::basic_syntax_group|regbase::emacs_ex) == (this->flags() & (regbase::main_option_type | regbase::emacs_ex)))
967
10
         )
968
10
      )
969
10
   {
970
      // OK we have a perl or emacs regex, check for a '?':
971
10
      if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
972
0
      {
973
         // whitespace skip:
974
0
         while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
975
0
            ++m_position;
976
0
      }
977
10
      if((m_position != m_end) && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question))
978
0
      {
979
0
         greedy = false;
980
0
         ++m_position;
981
0
      }
982
      // for perl regexes only check for possessive ++ repeats.
983
10
      if((m_position != m_end)
984
10
         && (0 == (this->flags() & regbase::main_option_type)) 
985
10
         && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_plus))
986
0
      {
987
0
         possessive = true;
988
0
         ++m_position;
989
0
      }
990
10
   }
991
10
   if(0 == this->m_last_state)
992
0
   {
993
0
      fail(regex_constants::error_badrepeat, std::distance(m_base, m_position), "Nothing to repeat.");
994
0
      return false;
995
0
   }
996
10
   if(this->m_last_state->type == syntax_element_endmark)
997
5
   {
998
      // insert a repeat before the '(' matching the last ')':
999
5
      insert_point = this->m_paren_start;
1000
5
   }
1001
5
   else if((this->m_last_state->type == syntax_element_literal) && (static_cast<re_literal*>(this->m_last_state)->length > 1))
1002
0
   {
1003
      // the last state was a literal with more than one character, split it in two:
1004
0
      re_literal* lit = static_cast<re_literal*>(this->m_last_state);
1005
0
      charT c = (static_cast<charT*>(static_cast<void*>(lit+1)))[lit->length - 1];
1006
0
      lit->length -= 1;
1007
      // now append new state:
1008
0
      lit = static_cast<re_literal*>(this->append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
1009
0
      lit->length = 1;
1010
0
      (static_cast<charT*>(static_cast<void*>(lit+1)))[0] = c;
1011
0
      insert_point = this->getoffset(this->m_last_state);
1012
0
   }
1013
5
   else
1014
5
   {
1015
      // repeat the last state whatever it was, need to add some error checking here:
1016
5
      switch(this->m_last_state->type)
1017
5
      {
1018
0
      case syntax_element_start_line:
1019
0
      case syntax_element_end_line:
1020
0
      case syntax_element_word_boundary:
1021
0
      case syntax_element_within_word:
1022
0
      case syntax_element_word_start:
1023
0
      case syntax_element_word_end:
1024
0
      case syntax_element_buffer_start:
1025
0
      case syntax_element_buffer_end:
1026
0
      case syntax_element_alt:
1027
0
      case syntax_element_soft_buffer_end:
1028
0
      case syntax_element_restart_continue:
1029
0
      case syntax_element_jump:
1030
0
      case syntax_element_startmark:
1031
0
      case syntax_element_backstep:
1032
         // can't legally repeat any of the above:
1033
0
         fail(regex_constants::error_badrepeat, m_position - m_base);
1034
0
         return false;
1035
5
      default:
1036
         // do nothing...
1037
5
         break;
1038
5
      }
1039
5
      insert_point = this->getoffset(this->m_last_state);
1040
5
   }
1041
   //
1042
   // OK we now know what to repeat, so insert the repeat around it:
1043
   //
1044
10
   re_repeat* rep = static_cast<re_repeat*>(this->insert_state(insert_point, syntax_element_rep, re_repeater_size));
1045
10
   rep->min = low;
1046
10
   rep->max = high;
1047
10
   rep->greedy = greedy;
1048
10
   rep->leading = false;
1049
   // store our repeater position for later:
1050
10
   std::ptrdiff_t rep_off = this->getoffset(rep);
1051
   // and append a back jump to the repeat:
1052
10
   re_jump* jmp = static_cast<re_jump*>(this->append_state(syntax_element_jump, sizeof(re_jump)));
1053
10
   jmp->alt.i = rep_off - this->getoffset(jmp);
1054
10
   this->m_pdata->m_data.align();
1055
   // now fill in the alt jump for the repeat:
1056
10
   rep = static_cast<re_repeat*>(this->getaddress(rep_off));
1057
10
   rep->alt.i = this->m_pdata->m_data.size() - rep_off;
1058
   //
1059
   // If the repeat is possessive then bracket the repeat with a (?>...)
1060
   // independent sub-expression construct:
1061
   //
1062
10
   if(possessive)
1063
0
   {
1064
0
      if(m_position != m_end)
1065
0
      {
1066
         //
1067
         // Check for illegal following quantifier, we have to do this here, because
1068
         // the extra states we insert below circumvents our usual error checking :-(
1069
         //
1070
0
         bool contin = false;
1071
0
         do
1072
0
         {
1073
0
            if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
1074
0
            {
1075
               // whitespace skip:
1076
0
               while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1077
0
                  ++m_position;
1078
0
            }
1079
0
            if (m_position != m_end)
1080
0
            {
1081
0
               switch (this->m_traits.syntax_type(*m_position))
1082
0
               {
1083
0
               case regex_constants::syntax_star:
1084
0
               case regex_constants::syntax_plus:
1085
0
               case regex_constants::syntax_question:
1086
0
               case regex_constants::syntax_open_brace:
1087
0
                  fail(regex_constants::error_badrepeat, m_position - m_base);
1088
0
                  return false;
1089
0
               case regex_constants::syntax_open_mark:
1090
                  // Do we have a comment?  If so we need to skip it here...
1091
0
                  if ((m_position + 2 < m_end) && this->m_traits.syntax_type(*(m_position + 1)) == regex_constants::syntax_question
1092
0
                     && this->m_traits.syntax_type(*(m_position + 2)) == regex_constants::syntax_hash)
1093
0
                  {
1094
0
                     while ((m_position != m_end)
1095
0
                        && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark)) {
1096
0
                     }
1097
0
                     contin = true;
1098
0
                  }
1099
0
                  else
1100
0
                     contin = false;
1101
0
               }
1102
0
            }
1103
0
            else
1104
0
               contin = false;
1105
0
         } while (contin);
1106
0
      }
1107
0
      re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));
1108
0
      pb->index = -3;
1109
0
      pb->icase = this->flags() & regbase::icase;
1110
0
      jmp = static_cast<re_jump*>(this->insert_state(insert_point + sizeof(re_brace), syntax_element_jump, sizeof(re_jump)));
1111
0
      this->m_pdata->m_data.align();
1112
0
      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
1113
0
      pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
1114
0
      pb->index = -3;
1115
0
      pb->icase = this->flags() & regbase::icase;
1116
0
   }
1117
10
   return true;
1118
10
}
1119
1120
template <class charT, class traits>
1121
bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
1122
0
{
1123
0
   static const char incomplete_message[] = "Missing } in quantified repetition.";
1124
   //
1125
   // parse a repeat-range:
1126
   //
1127
0
   std::size_t min, max;
1128
0
   std::intmax_t v;
1129
   // skip whitespace:
1130
0
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1131
0
      ++m_position;
1132
0
   if(this->m_position == this->m_end)
1133
0
   {
1134
0
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1135
0
      {
1136
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1137
0
         return false;
1138
0
      }
1139
      // Treat the opening '{' as a literal character, rewind to start of error:
1140
0
      --m_position;
1141
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1142
0
      return parse_literal();
1143
0
   }
1144
   // get min:
1145
0
   v = this->m_traits.toi(m_position, m_end, 10);
1146
   // skip whitespace:
1147
0
   if((v < 0) || (v > umax()))
1148
0
   {
1149
0
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1150
0
      {
1151
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1152
0
         return false;
1153
0
      }
1154
      // Treat the opening '{' as a literal character, rewind to start of error:
1155
0
      --m_position;
1156
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1157
0
      return parse_literal();
1158
0
   }
1159
0
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1160
0
      ++m_position;
1161
0
   if(this->m_position == this->m_end)
1162
0
   {
1163
0
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1164
0
      {
1165
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1166
0
         return false;
1167
0
      }
1168
      // Treat the opening '{' as a literal character, rewind to start of error:
1169
0
      --m_position;
1170
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1171
0
      return parse_literal();
1172
0
   }
1173
0
   min = static_cast<std::size_t>(v);
1174
   // see if we have a comma:
1175
0
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_comma)
1176
0
   {
1177
      // move on and error check:
1178
0
      ++m_position;
1179
      // skip whitespace:
1180
0
      while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1181
0
         ++m_position;
1182
0
      if(this->m_position == this->m_end)
1183
0
      {
1184
0
         if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1185
0
         {
1186
0
            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1187
0
            return false;
1188
0
         }
1189
         // Treat the opening '{' as a literal character, rewind to start of error:
1190
0
         --m_position;
1191
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1192
0
         return parse_literal();
1193
0
      }
1194
      // get the value if any:
1195
0
      v = this->m_traits.toi(m_position, m_end, 10);
1196
0
      max = ((v >= 0) && (v < umax())) ? (std::size_t)v : (std::numeric_limits<std::size_t>::max)();
1197
0
   }
1198
0
   else
1199
0
   {
1200
      // no comma, max = min:
1201
0
      max = min;
1202
0
   }
1203
   // skip whitespace:
1204
0
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1205
0
      ++m_position;
1206
   // OK now check trailing }:
1207
0
   if(this->m_position == this->m_end)
1208
0
   {
1209
0
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1210
0
      {
1211
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1212
0
         return false;
1213
0
      }
1214
      // Treat the opening '{' as a literal character, rewind to start of error:
1215
0
      --m_position;
1216
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1217
0
      return parse_literal();
1218
0
   }
1219
0
   if(isbasic)
1220
0
   {
1221
0
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_escape)
1222
0
      {
1223
0
         ++m_position;
1224
0
         if(this->m_position == this->m_end)
1225
0
         {
1226
0
            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1227
0
            return false;
1228
0
         }
1229
0
      }
1230
0
      else
1231
0
      {
1232
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1233
0
         return false;
1234
0
      }
1235
0
   }
1236
0
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_brace)
1237
0
      ++m_position;
1238
0
   else
1239
0
   {
1240
      // Treat the opening '{' as a literal character, rewind to start of error:
1241
0
      --m_position;
1242
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1243
0
      return parse_literal();
1244
0
   }
1245
   //
1246
   // finally go and add the repeat, unless error:
1247
   //
1248
0
   if(min > max)
1249
0
   {
1250
      // Backtrack to error location:
1251
0
      m_position -= 2;
1252
0
      while(this->m_traits.isctype(*m_position, this->m_word_mask)) --m_position;
1253
0
         ++m_position;
1254
0
      fail(regex_constants::error_badbrace, m_position - m_base);
1255
0
      return false;
1256
0
   }
1257
0
   return parse_repeat(min, max);
1258
0
}
1259
1260
template <class charT, class traits>
1261
bool basic_regex_parser<charT, traits>::parse_alt()
1262
0
{
1263
   //
1264
   // error check: if there have been no previous states,
1265
   // or if the last state was a '(' then error:
1266
   //
1267
0
   if(
1268
0
      ((this->m_last_state == 0) || (this->m_last_state->type == syntax_element_startmark))
1269
0
      &&
1270
0
      !(
1271
0
         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)
1272
0
           &&
1273
0
         ((this->flags() & regbase::no_empty_expressions) == 0)
1274
0
        )
1275
0
      )
1276
0
   {
1277
0
      fail(regex_constants::error_empty, this->m_position - this->m_base, "A regular expression cannot start with the alternation operator |.");
1278
0
      return false;
1279
0
   }
1280
   //
1281
   // Reset mark count if required:
1282
   //
1283
0
   if(m_max_mark < m_mark_count)
1284
0
      m_max_mark = m_mark_count;
1285
0
   if(m_mark_reset >= 0)
1286
0
      m_mark_count = m_mark_reset;
1287
1288
0
   ++m_position;
1289
   //
1290
   // we need to append a trailing jump: 
1291
   //
1292
0
   re_syntax_base* pj = this->append_state(BOOST_REGEX_DETAIL_NS::syntax_element_jump, sizeof(re_jump));
1293
0
   std::ptrdiff_t jump_offset = this->getoffset(pj);
1294
   //
1295
   // now insert the alternative:
1296
   //
1297
0
   re_alt* palt = static_cast<re_alt*>(this->insert_state(this->m_alt_insert_point, syntax_element_alt, re_alt_size));
1298
0
   jump_offset += re_alt_size;
1299
0
   this->m_pdata->m_data.align();
1300
0
   palt->alt.i = this->m_pdata->m_data.size() - this->getoffset(palt);
1301
   //
1302
   // update m_alt_insert_point so that the next alternate gets
1303
   // inserted at the start of the second of the two we've just created:
1304
   //
1305
0
   this->m_alt_insert_point = this->m_pdata->m_data.size();
1306
   //
1307
   // the start of this alternative must have a case changes state
1308
   // if the current block has messed around with case changes:
1309
   //
1310
0
   if(m_has_case_change)
1311
0
   {
1312
0
      static_cast<re_case*>(
1313
0
         this->append_state(syntax_element_toggle_case, sizeof(re_case))
1314
0
         )->icase = this->m_icase;
1315
0
   }
1316
   //
1317
   // push the alternative onto our stack, a recursive
1318
   // implementation here is easier to understand (and faster
1319
   // as it happens), but causes all kinds of stack overflow problems
1320
   // on programs with small stacks (COM+).
1321
   //
1322
0
   m_alt_jumps.push_back(jump_offset);
1323
0
   return true;
1324
0
}
1325
1326
template <class charT, class traits>
1327
bool basic_regex_parser<charT, traits>::parse_set()
1328
5
{
1329
5
   static const char incomplete_message[] = "Character set declaration starting with [ terminated prematurely - either no ] was found or the set had no content.";
1330
5
   ++m_position;
1331
5
   if(m_position == m_end)
1332
0
   {
1333
0
      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1334
0
      return false;
1335
0
   }
1336
5
   basic_char_set<charT, traits> char_set;
1337
1338
5
   const charT* base = m_position;  // where the '[' was
1339
5
   const charT* item_base = m_position;  // where the '[' or '^' was
1340
1341
10
   while(m_position != m_end)
1342
10
   {
1343
10
      switch(this->m_traits.syntax_type(*m_position))
1344
10
      {
1345
0
      case regex_constants::syntax_caret:
1346
0
         if(m_position == base)
1347
0
         {
1348
0
            char_set.negate();
1349
0
            ++m_position;
1350
0
            item_base = m_position;
1351
0
         }
1352
0
         else
1353
0
            parse_set_literal(char_set);
1354
0
         break;
1355
5
      case regex_constants::syntax_close_set:
1356
5
         if(m_position == item_base)
1357
0
         {
1358
0
            parse_set_literal(char_set);
1359
0
            break;
1360
0
         }
1361
5
         else
1362
5
         {
1363
5
            ++m_position;
1364
5
            if(0 == this->append_set(char_set))
1365
0
            {
1366
0
               fail(regex_constants::error_ctype, m_position - m_base);
1367
0
               return false;
1368
0
            }
1369
5
         }
1370
5
         return true;
1371
0
      case regex_constants::syntax_open_set:
1372
0
         if(parse_inner_set(char_set))
1373
0
            break;
1374
0
         return true;
1375
0
      case regex_constants::syntax_escape:
1376
0
         {
1377
            // 
1378
            // look ahead and see if this is a character class shortcut
1379
            // \d \w \s etc...
1380
            //
1381
0
            ++m_position;
1382
0
            if(this->m_traits.escape_syntax_type(*m_position)
1383
0
               == regex_constants::escape_type_class)
1384
0
            {
1385
0
               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
1386
0
               if(m != 0)
1387
0
               {
1388
0
                  char_set.add_class(m);
1389
0
                  ++m_position;
1390
0
                  break;
1391
0
               }
1392
0
            }
1393
0
            else if(this->m_traits.escape_syntax_type(*m_position)
1394
0
               == regex_constants::escape_type_not_class)
1395
0
            {
1396
               // negated character class:
1397
0
               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
1398
0
               if(m != 0)
1399
0
               {
1400
0
                  char_set.add_negated_class(m);
1401
0
                  ++m_position;
1402
0
                  break;
1403
0
               }
1404
0
            }
1405
            // not a character class, just a regular escape:
1406
0
            --m_position;
1407
0
            parse_set_literal(char_set);
1408
0
            break;
1409
0
         }
1410
5
      default:
1411
5
         parse_set_literal(char_set);
1412
5
         break;
1413
10
      }
1414
10
   }
1415
0
   return m_position != m_end;
1416
5
}
1417
1418
template <class charT, class traits>
1419
bool basic_regex_parser<charT, traits>::parse_inner_set(basic_char_set<charT, traits>& char_set)
1420
0
{
1421
0
   static const char incomplete_message[] = "Character class declaration starting with [ terminated prematurely - either no ] was found or the set had no content.";
1422
   //
1423
   // we have either a character class [:name:]
1424
   // a collating element [.name.]
1425
   // or an equivalence class [=name=]
1426
   //
1427
0
   if(m_end == ++m_position)
1428
0
   {
1429
0
      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1430
0
      return false;
1431
0
   }
1432
0
   switch(this->m_traits.syntax_type(*m_position))
1433
0
   {
1434
0
   case regex_constants::syntax_dot:
1435
      //
1436
      // a collating element is treated as a literal:
1437
      //
1438
0
      --m_position;
1439
0
      parse_set_literal(char_set);
1440
0
      return true;
1441
0
   case regex_constants::syntax_colon:
1442
0
      {
1443
      // check that character classes are actually enabled:
1444
0
      if((this->flags() & (regbase::main_option_type | regbase::no_char_classes)) 
1445
0
         == (regbase::basic_syntax_group  | regbase::no_char_classes))
1446
0
      {
1447
0
         --m_position;
1448
0
         parse_set_literal(char_set);
1449
0
         return true;
1450
0
      }
1451
      // skip the ':'
1452
0
      if(m_end == ++m_position)
1453
0
      {
1454
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1455
0
         return false;
1456
0
      }
1457
0
      const charT* name_first = m_position;
1458
      // skip at least one character, then find the matching ':]'
1459
0
      if(m_end == ++m_position)
1460
0
      {
1461
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1462
0
         return false;
1463
0
      }
1464
0
      while((m_position != m_end) 
1465
0
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_colon)) 
1466
0
         ++m_position;
1467
0
      const charT* name_last = m_position;
1468
0
      if(m_end == m_position)
1469
0
      {
1470
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1471
0
         return false;
1472
0
      }
1473
0
      if((m_end == ++m_position) 
1474
0
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1475
0
      {
1476
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1477
0
         return false;
1478
0
      }
1479
      //
1480
      // check for negated class:
1481
      //
1482
0
      bool negated = false;
1483
0
      if(this->m_traits.syntax_type(*name_first) == regex_constants::syntax_caret)
1484
0
      {
1485
0
         ++name_first;
1486
0
         negated = true;
1487
0
      }
1488
0
      typedef typename traits::char_class_type m_type;
1489
0
      m_type m = this->m_traits.lookup_classname(name_first, name_last);
1490
0
      if(m == 0)
1491
0
      {
1492
0
         if(char_set.empty() && (name_last - name_first == 1))
1493
0
         {
1494
            // maybe a special case:
1495
0
            ++m_position;
1496
0
            if( (m_position != m_end) 
1497
0
               && (this->m_traits.syntax_type(*m_position) 
1498
0
                  == regex_constants::syntax_close_set))
1499
0
            {
1500
0
               if(this->m_traits.escape_syntax_type(*name_first) 
1501
0
                  == regex_constants::escape_type_left_word)
1502
0
               {
1503
0
                  ++m_position;
1504
0
                  this->append_state(syntax_element_word_start);
1505
0
                  return false;
1506
0
               }
1507
0
               if(this->m_traits.escape_syntax_type(*name_first) 
1508
0
                  == regex_constants::escape_type_right_word)
1509
0
               {
1510
0
                  ++m_position;
1511
0
                  this->append_state(syntax_element_word_end);
1512
0
                  return false;
1513
0
               }
1514
0
            }
1515
0
         }
1516
0
         fail(regex_constants::error_ctype, name_first - m_base);
1517
0
         return false;
1518
0
      }
1519
0
      if(!negated)
1520
0
         char_set.add_class(m);
1521
0
      else
1522
0
         char_set.add_negated_class(m);
1523
0
      ++m_position;
1524
0
      break;
1525
0
   }
1526
0
   case regex_constants::syntax_equal:
1527
0
      {
1528
      // skip the '='
1529
0
      if(m_end == ++m_position)
1530
0
      {
1531
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1532
0
         return false;
1533
0
      }
1534
0
      const charT* name_first = m_position;
1535
      // skip at least one character, then find the matching '=]'
1536
0
      if(m_end == ++m_position)
1537
0
      {
1538
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1539
0
         return false;
1540
0
      }
1541
0
      while((m_position != m_end) 
1542
0
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)) 
1543
0
         ++m_position;
1544
0
      const charT* name_last = m_position;
1545
0
      if(m_end == m_position)
1546
0
      {
1547
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1548
0
         return false;
1549
0
      }
1550
0
      if((m_end == ++m_position) 
1551
0
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1552
0
      {
1553
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1554
0
         return false;
1555
0
      }
1556
0
      string_type m = this->m_traits.lookup_collatename(name_first, name_last);
1557
0
      if(m.empty() || (m.size() > 2))
1558
0
      {
1559
0
         fail(regex_constants::error_collate, name_first - m_base);
1560
0
         return false;
1561
0
      }
1562
0
      digraph<charT> d;
1563
0
      d.first = m[0];
1564
0
      if(m.size() > 1)
1565
0
         d.second = m[1];
1566
0
      else
1567
0
         d.second = 0;
1568
0
      char_set.add_equivalent(d);
1569
0
      ++m_position;
1570
0
      break;
1571
0
   }
1572
0
   default:
1573
0
      --m_position;
1574
0
      parse_set_literal(char_set);
1575
0
      break;
1576
0
   }
1577
0
   return true;
1578
0
}
1579
1580
template <class charT, class traits>
1581
void basic_regex_parser<charT, traits>::parse_set_literal(basic_char_set<charT, traits>& char_set)
1582
5
{
1583
5
   digraph<charT> start_range(get_next_set_literal(char_set));
1584
5
   if(m_end == m_position)
1585
0
   {
1586
0
      fail(regex_constants::error_brack, m_position - m_base);
1587
0
      return;
1588
0
   }
1589
5
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
1590
5
   {
1591
      // we have a range:
1592
5
      if(m_end == ++m_position)
1593
0
      {
1594
0
         fail(regex_constants::error_brack, m_position - m_base);
1595
0
         return;
1596
0
      }
1597
5
      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set)
1598
5
      {
1599
5
         digraph<charT> end_range = get_next_set_literal(char_set);
1600
5
         char_set.add_range(start_range, end_range);
1601
5
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
1602
0
         {
1603
0
            if(m_end == ++m_position)
1604
0
            {
1605
0
               fail(regex_constants::error_brack, m_position - m_base);
1606
0
               return;
1607
0
            }
1608
0
            if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_set)
1609
0
            {
1610
               // trailing - :
1611
0
               --m_position;
1612
0
               return;
1613
0
            }
1614
0
            fail(regex_constants::error_range, m_position - m_base);
1615
0
            return;
1616
0
         }
1617
5
         return;
1618
5
      }
1619
0
      --m_position;
1620
0
   }
1621
0
   char_set.add_single(start_range);
1622
0
}
1623
1624
template <class charT, class traits>
1625
digraph<charT> basic_regex_parser<charT, traits>::get_next_set_literal(basic_char_set<charT, traits>& char_set)
1626
10
{
1627
10
   digraph<charT> result;
1628
10
   switch(this->m_traits.syntax_type(*m_position))
1629
10
   {
1630
0
   case regex_constants::syntax_dash:
1631
0
      if(!char_set.empty())
1632
0
      {
1633
         // see if we are at the end of the set:
1634
0
         if((++m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1635
0
         {
1636
0
            fail(regex_constants::error_range, m_position - m_base);
1637
0
            return result;
1638
0
         }
1639
0
         --m_position;
1640
0
      }
1641
0
      result.first = *m_position++;
1642
0
      return result;
1643
0
   case regex_constants::syntax_escape:
1644
      // check to see if escapes are supported first:
1645
0
      if(this->flags() & regex_constants::no_escape_in_lists)
1646
0
      {
1647
0
         result = *m_position++;
1648
0
         break;
1649
0
      }
1650
0
      ++m_position;
1651
0
      result = unescape_character();
1652
0
      break;
1653
0
   case regex_constants::syntax_open_set:
1654
0
   {
1655
0
      if(m_end == ++m_position)
1656
0
      {
1657
0
         fail(regex_constants::error_collate, m_position - m_base);
1658
0
         return result;
1659
0
      }
1660
0
      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)
1661
0
      {
1662
0
         --m_position;
1663
0
         result.first = *m_position;
1664
0
         ++m_position;
1665
0
         return result;
1666
0
      }
1667
0
      if(m_end == ++m_position)
1668
0
      {
1669
0
         fail(regex_constants::error_collate, m_position - m_base);
1670
0
         return result;
1671
0
      }
1672
0
      const charT* name_first = m_position;
1673
      // skip at least one character, then find the matching ':]'
1674
0
      if(m_end == ++m_position)
1675
0
      {
1676
0
         fail(regex_constants::error_collate, name_first - m_base);
1677
0
         return result;
1678
0
      }
1679
0
      while((m_position != m_end) 
1680
0
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)) 
1681
0
         ++m_position;
1682
0
      const charT* name_last = m_position;
1683
0
      if(m_end == m_position)
1684
0
      {
1685
0
         fail(regex_constants::error_collate, name_first - m_base);
1686
0
         return result;
1687
0
      }
1688
0
      if((m_end == ++m_position) 
1689
0
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1690
0
      {
1691
0
         fail(regex_constants::error_collate, name_first - m_base);
1692
0
         return result;
1693
0
      }
1694
0
      ++m_position;
1695
0
      string_type s = this->m_traits.lookup_collatename(name_first, name_last);
1696
0
      if(s.empty() || (s.size() > 2))
1697
0
      {
1698
0
         fail(regex_constants::error_collate, name_first - m_base);
1699
0
         return result;
1700
0
      }
1701
0
      result.first = s[0];
1702
0
      if(s.size() > 1)
1703
0
         result.second = s[1];
1704
0
      else
1705
0
         result.second = 0;
1706
0
      return result;
1707
0
   }
1708
10
   default:
1709
10
      result = *m_position++;
1710
10
   }
1711
10
   return result;
1712
10
}
1713
1714
//
1715
// does a value fit in the specified charT type?
1716
//
1717
template <class charT>
1718
bool valid_value(charT, std::intmax_t v, const std::integral_constant<bool, true>&)
1719
0
{
1720
0
   return (v >> (sizeof(charT) * CHAR_BIT)) == 0;
1721
0
}
1722
template <class charT>
1723
bool valid_value(charT, std::intmax_t, const std::integral_constant<bool, false>&)
1724
{
1725
   return true; // v will alsways fit in a charT
1726
}
1727
template <class charT>
1728
bool valid_value(charT c, std::intmax_t v)
1729
0
{
1730
0
   return valid_value(c, v, std::integral_constant<bool, (sizeof(charT) < sizeof(std::intmax_t))>());
1731
0
}
1732
1733
template <class charT, class traits>
1734
charT basic_regex_parser<charT, traits>::unescape_character()
1735
5
{
1736
#ifdef BOOST_REGEX_MSVC
1737
#pragma warning(push)
1738
#pragma warning(disable:4127)
1739
#endif
1740
5
   charT result(0);
1741
5
   if(m_position == m_end)
1742
0
   {
1743
0
      fail(regex_constants::error_escape, m_position - m_base, "Escape sequence terminated prematurely.");
1744
0
      return false;
1745
0
   }
1746
5
   switch(this->m_traits.escape_syntax_type(*m_position))
1747
5
   {
1748
0
   case regex_constants::escape_type_control_a:
1749
0
      result = charT('\a');
1750
0
      break;
1751
0
   case regex_constants::escape_type_e:
1752
0
      result = charT(27);
1753
0
      break;
1754
0
   case regex_constants::escape_type_control_f:
1755
0
      result = charT('\f');
1756
0
      break;
1757
0
   case regex_constants::escape_type_control_n:
1758
0
      result = charT('\n');
1759
0
      break;
1760
0
   case regex_constants::escape_type_control_r:
1761
0
      result = charT('\r');
1762
0
      break;
1763
0
   case regex_constants::escape_type_control_t:
1764
0
      result = charT('\t');
1765
0
      break;
1766
0
   case regex_constants::escape_type_control_v:
1767
0
      result = charT('\v');
1768
0
      break;
1769
0
   case regex_constants::escape_type_word_assert:
1770
0
      result = charT('\b');
1771
0
      break;
1772
0
   case regex_constants::escape_type_ascii_control:
1773
0
      ++m_position;
1774
0
      if(m_position == m_end)
1775
0
      {
1776
         // Rewind to start of escape:
1777
0
         --m_position;
1778
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1779
0
         fail(regex_constants::error_escape, m_position - m_base, "ASCII escape sequence terminated prematurely.");
1780
0
         return result;
1781
0
      }
1782
0
      result = static_cast<charT>(*m_position % 32);
1783
0
      break;
1784
0
   case regex_constants::escape_type_hex:
1785
0
      ++m_position;
1786
0
      if(m_position == m_end)
1787
0
      {
1788
         // Rewind to start of escape:
1789
0
         --m_position;
1790
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1791
0
         fail(regex_constants::error_escape, m_position - m_base, "Hexadecimal escape sequence terminated prematurely.");
1792
0
         return result;
1793
0
      }
1794
      // maybe have \x{ddd}
1795
0
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
1796
0
      {
1797
0
         ++m_position;
1798
0
         if(m_position == m_end)
1799
0
         {
1800
            // Rewind to start of escape:
1801
0
            --m_position;
1802
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1803
0
            fail(regex_constants::error_escape, m_position - m_base, "Missing } in hexadecimal escape sequence.");
1804
0
            return result;
1805
0
         }
1806
0
         std::intmax_t i = this->m_traits.toi(m_position, m_end, 16);
1807
0
         if((m_position == m_end)
1808
0
            || (i < 0)
1809
0
            || ((std::numeric_limits<charT>::is_specialized) && (i > (std::intmax_t)(std::numeric_limits<charT>::max)()))
1810
0
            || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
1811
0
         {
1812
            // Rewind to start of escape:
1813
0
            --m_position;
1814
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1815
0
            fail(regex_constants::error_badbrace, m_position - m_base, "Hexadecimal escape sequence was invalid.");
1816
0
            return result;
1817
0
         }
1818
0
         ++m_position;
1819
0
         result = charT(i);
1820
0
      }
1821
0
      else
1822
0
      {
1823
0
         std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), static_cast<std::ptrdiff_t>(m_end - m_position));
1824
0
         std::intmax_t i = this->m_traits.toi(m_position, m_position + len, 16);
1825
0
         if((i < 0)
1826
0
            || !valid_value(charT(0), i))
1827
0
         {
1828
            // Rewind to start of escape:
1829
0
            --m_position;
1830
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1831
0
            fail(regex_constants::error_escape, m_position - m_base, "Escape sequence did not encode a valid character.");
1832
0
            return result;
1833
0
         }
1834
0
         result = charT(i);
1835
0
      }
1836
0
      return result;
1837
0
   case regex_constants::syntax_digit:
1838
0
      {
1839
      // an octal escape sequence, the first character must be a zero
1840
      // followed by up to 3 octal digits:
1841
0
      std::ptrdiff_t len = (std::min)(std::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));
1842
0
      const charT* bp = m_position;
1843
0
      std::intmax_t val = this->m_traits.toi(bp, bp + 1, 8);
1844
0
      if(val != 0)
1845
0
      {
1846
         // Rewind to start of escape:
1847
0
         --m_position;
1848
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1849
         // Oops not an octal escape after all:
1850
0
         fail(regex_constants::error_escape, m_position - m_base, "Invalid octal escape sequence.");
1851
0
         return result;
1852
0
      }
1853
0
      val = this->m_traits.toi(m_position, m_position + len, 8);
1854
0
      if((val < 0) || (val > (std::intmax_t)(std::numeric_limits<charT>::max)()))
1855
0
      {
1856
         // Rewind to start of escape:
1857
0
         --m_position;
1858
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1859
0
         fail(regex_constants::error_escape, m_position - m_base, "Octal escape sequence is invalid.");
1860
0
         return result;
1861
0
      }
1862
0
      return static_cast<charT>(val);
1863
0
      }
1864
0
   case regex_constants::escape_type_named_char:
1865
0
      {
1866
0
         ++m_position;
1867
0
         if(m_position == m_end)
1868
0
         {
1869
            // Rewind to start of escape:
1870
0
            --m_position;
1871
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1872
0
            fail(regex_constants::error_escape, m_position - m_base);
1873
0
            return false;
1874
0
         }
1875
         // maybe have \N{name}
1876
0
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
1877
0
         {
1878
0
            const charT* base = m_position;
1879
            // skip forward until we find enclosing brace:
1880
0
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
1881
0
               ++m_position;
1882
0
            if(m_position == m_end)
1883
0
            {
1884
               // Rewind to start of escape:
1885
0
               --m_position;
1886
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1887
0
               fail(regex_constants::error_escape, m_position - m_base);
1888
0
               return false;
1889
0
            }
1890
0
            string_type s = this->m_traits.lookup_collatename(++base, m_position++);
1891
0
            if(s.empty())
1892
0
            {
1893
               // Rewind to start of escape:
1894
0
               --m_position;
1895
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1896
0
               fail(regex_constants::error_collate, m_position - m_base);
1897
0
               return false;
1898
0
            }
1899
0
            if(s.size() == 1)
1900
0
            {
1901
0
               return s[0];
1902
0
            }
1903
0
         }
1904
         // fall through is a failure:
1905
         // Rewind to start of escape:
1906
0
         --m_position;
1907
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1908
0
         fail(regex_constants::error_escape, m_position - m_base);
1909
0
         return false;
1910
0
      }
1911
5
   default:
1912
5
      result = *m_position;
1913
5
      break;
1914
5
   }
1915
5
   ++m_position;
1916
5
   return result;
1917
#ifdef BOOST_REGEX_MSVC
1918
#pragma warning(pop)
1919
#endif
1920
5
}
1921
1922
template <class charT, class traits>
1923
bool basic_regex_parser<charT, traits>::parse_backref()
1924
0
{
1925
0
   BOOST_REGEX_ASSERT(m_position != m_end);
1926
0
   const charT* pc = m_position;
1927
0
   std::intmax_t i = this->m_traits.toi(pc, pc + 1, 10);
1928
0
   if((i == 0) || (((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group) && (this->flags() & regbase::no_bk_refs)))
1929
0
   {
1930
      // not a backref at all but an octal escape sequence:
1931
0
      charT c = unescape_character();
1932
0
      this->append_literal(c);
1933
0
   }
1934
0
   else if((i > 0) && (this->m_backrefs.test((std::size_t)i)))
1935
0
   {
1936
0
      m_position = pc;
1937
0
      re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
1938
0
      pb->index = (int)i;
1939
0
      pb->icase = this->flags() & regbase::icase;
1940
0
   }
1941
0
   else
1942
0
   {
1943
      // Rewind to start of escape:
1944
0
      --m_position;
1945
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1946
0
      fail(regex_constants::error_backref, m_position - m_base);
1947
0
      return false;
1948
0
   }
1949
0
   return true;
1950
0
}
1951
1952
template <class charT, class traits>
1953
bool basic_regex_parser<charT, traits>::parse_QE()
1954
0
{
1955
#ifdef BOOST_REGEX_MSVC
1956
#pragma warning(push)
1957
#pragma warning(disable:4127)
1958
#endif
1959
   //
1960
   // parse a \Q...\E sequence:
1961
   //
1962
0
   ++m_position; // skip the Q
1963
0
   const charT* start = m_position;
1964
0
   const charT* end;
1965
0
   do
1966
0
   {
1967
0
      while((m_position != m_end) 
1968
0
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape))
1969
0
         ++m_position;
1970
0
      if(m_position == m_end)
1971
0
      {
1972
         //  a \Q...\E sequence may terminate with the end of the expression:
1973
0
         end = m_position;
1974
0
         break;  
1975
0
      }
1976
0
      if(++m_position == m_end) // skip the escape
1977
0
      {
1978
0
         fail(regex_constants::error_escape, m_position - m_base, "Unterminated \\Q...\\E sequence.");
1979
0
         return false;
1980
0
      }
1981
      // check to see if it's a \E:
1982
0
      if(this->m_traits.escape_syntax_type(*m_position) == regex_constants::escape_type_E)
1983
0
      {
1984
0
         ++m_position;
1985
0
         end = m_position - 2;
1986
0
         break;
1987
0
      }
1988
      // otherwise go round again:
1989
0
   }while(true);
1990
   //
1991
   // now add all the character between the two escapes as literals:
1992
   //
1993
0
   while(start != end)
1994
0
   {
1995
0
      this->append_literal(*start);
1996
0
      ++start;
1997
0
   }
1998
0
   return true;
1999
#ifdef BOOST_REGEX_MSVC
2000
#pragma warning(pop)
2001
#endif
2002
0
}
2003
2004
template <class charT, class traits>
2005
bool basic_regex_parser<charT, traits>::parse_perl_extension()
2006
0
{
2007
0
   if(++m_position == m_end)
2008
0
   {
2009
      // Rewind to start of (? sequence:
2010
0
      --m_position;
2011
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2012
0
      fail(regex_constants::error_perl_extension, m_position - m_base);
2013
0
      return false;
2014
0
   }
2015
   //
2016
   // treat comments as a special case, as these
2017
   // are the only ones that don't start with a leading
2018
   // startmark state:
2019
   //
2020
0
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_hash)
2021
0
   {
2022
0
      while((m_position != m_end) 
2023
0
         && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))
2024
0
      {}
2025
0
      return true;
2026
0
   }
2027
   //
2028
   // backup some state, and prepare the way:
2029
   //
2030
0
   int markid = 0;
2031
0
   std::ptrdiff_t jump_offset = 0;
2032
0
   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
2033
0
   pb->icase = this->flags() & regbase::icase;
2034
0
   std::ptrdiff_t last_paren_start = this->getoffset(pb);
2035
   // back up insertion point for alternations, and set new point:
2036
0
   std::ptrdiff_t last_alt_point = m_alt_insert_point;
2037
0
   this->m_pdata->m_data.align();
2038
0
   m_alt_insert_point = this->m_pdata->m_data.size();
2039
0
   std::ptrdiff_t expected_alt_point = m_alt_insert_point;
2040
0
   bool restore_flags = true;
2041
0
   regex_constants::syntax_option_type old_flags = this->flags();
2042
0
   bool old_case_change = m_has_case_change;
2043
0
   m_has_case_change = false;
2044
0
   charT name_delim;
2045
0
   int mark_reset = m_mark_reset;
2046
0
   int max_mark = m_max_mark;
2047
0
   m_mark_reset = -1;
2048
0
   m_max_mark = m_mark_count;
2049
0
   std::intmax_t v;
2050
   //
2051
   // select the actual extension used:
2052
   //
2053
0
   switch(this->m_traits.syntax_type(*m_position))
2054
0
   {
2055
0
   case regex_constants::syntax_or:
2056
0
      m_mark_reset = m_mark_count;
2057
0
      BOOST_REGEX_FALLTHROUGH;
2058
0
   case regex_constants::syntax_colon:
2059
      //
2060
      // a non-capturing mark:
2061
      //
2062
0
      pb->index = markid = 0;
2063
0
      ++m_position;
2064
0
      break;
2065
0
   case regex_constants::syntax_digit:
2066
0
      {
2067
      //
2068
      // a recursive subexpression:
2069
      //
2070
0
      v = this->m_traits.toi(m_position, m_end, 10);
2071
0
      if((v < 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2072
0
      {
2073
         // Rewind to start of (? sequence:
2074
0
         --m_position;
2075
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2076
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "The recursive sub-expression refers to an invalid marking group, or is unterminated.");
2077
0
         return false;
2078
0
      }
2079
0
insert_recursion:
2080
0
      pb->index = markid = 0;
2081
0
      re_recurse* pr = static_cast<re_recurse*>(this->append_state(syntax_element_recurse, sizeof(re_recurse)));
2082
0
      pr->alt.i = (std::ptrdiff_t)v;
2083
0
      pr->state_id = 0;
2084
0
      static_cast<re_case*>(
2085
0
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2086
0
            )->icase = this->flags() & regbase::icase;
2087
0
      break;
2088
0
      }
2089
0
   case regex_constants::syntax_plus:
2090
      //
2091
      // A forward-relative recursive subexpression:
2092
      //
2093
0
      ++m_position;
2094
0
      v = this->m_traits.toi(m_position, m_end, 10);
2095
0
      if((v <= 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2096
0
      {
2097
         // Rewind to start of (? sequence:
2098
0
         --m_position;
2099
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2100
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2101
0
         return false;
2102
0
      }
2103
0
      if ((std::numeric_limits<std::intmax_t>::max)() - m_mark_count < v)
2104
0
      {
2105
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2106
0
         return false;
2107
0
      }
2108
0
      v += m_mark_count;
2109
0
      goto insert_recursion;
2110
0
   case regex_constants::syntax_dash:
2111
      //
2112
      // Possibly a backward-relative recursive subexpression:
2113
      //
2114
0
      ++m_position;
2115
0
      v = this->m_traits.toi(m_position, m_end, 10);
2116
0
      if(v <= 0)
2117
0
      {
2118
0
         --m_position;
2119
         // Oops not a relative recursion at all, but a (?-imsx) group:
2120
0
         goto option_group_jump;
2121
0
      }
2122
0
      v = static_cast<std::intmax_t>(m_mark_count) + 1 - v;
2123
0
      if(v <= 0)
2124
0
      {
2125
         // Rewind to start of (? sequence:
2126
0
         --m_position;
2127
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2128
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2129
0
         return false;
2130
0
      }
2131
0
      goto insert_recursion;
2132
0
   case regex_constants::syntax_equal:
2133
0
      pb->index = markid = -1;
2134
0
      ++m_position;
2135
0
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2136
0
      this->m_pdata->m_data.align();
2137
0
      m_alt_insert_point = this->m_pdata->m_data.size();
2138
0
      break;
2139
0
   case regex_constants::syntax_not:
2140
0
      pb->index = markid = -2;
2141
0
      ++m_position;
2142
0
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2143
0
      this->m_pdata->m_data.align();
2144
0
      m_alt_insert_point = this->m_pdata->m_data.size();
2145
0
      break;
2146
0
   case regex_constants::escape_type_left_word:
2147
0
      {
2148
         // a lookbehind assertion:
2149
0
         if(++m_position == m_end)
2150
0
         {
2151
            // Rewind to start of (? sequence:
2152
0
            --m_position;
2153
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2154
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2155
0
            return false;
2156
0
         }
2157
0
         regex_constants::syntax_type t = this->m_traits.syntax_type(*m_position);
2158
0
         if(t == regex_constants::syntax_not)
2159
0
            pb->index = markid = -2;
2160
0
         else if(t == regex_constants::syntax_equal)
2161
0
            pb->index = markid = -1;
2162
0
         else
2163
0
         {
2164
            // Probably a named capture which also starts (?< :
2165
0
            name_delim = '>';
2166
0
            --m_position;
2167
0
            goto named_capture_jump;
2168
0
         }
2169
0
         ++m_position;
2170
0
         jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2171
0
         this->append_state(syntax_element_backstep, sizeof(re_brace));
2172
0
         this->m_pdata->m_data.align();
2173
0
         m_alt_insert_point = this->m_pdata->m_data.size();
2174
0
         break;
2175
0
      }
2176
0
   case regex_constants::escape_type_right_word:
2177
      //
2178
      // an independent sub-expression:
2179
      //
2180
0
      pb->index = markid = -3;
2181
0
      ++m_position;
2182
0
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2183
0
      this->m_pdata->m_data.align();
2184
0
      m_alt_insert_point = this->m_pdata->m_data.size();
2185
0
      break;
2186
0
   case regex_constants::syntax_open_mark:
2187
0
      {
2188
      // a conditional expression:
2189
0
      pb->index = markid = -4;
2190
0
      if(++m_position == m_end)
2191
0
      {
2192
         // Rewind to start of (? sequence:
2193
0
         --m_position;
2194
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2195
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2196
0
         return false;
2197
0
      }
2198
0
      v = this->m_traits.toi(m_position, m_end, 10);
2199
0
      if(m_position == m_end)
2200
0
      {
2201
         // Rewind to start of (? sequence:
2202
0
         --m_position;
2203
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2204
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2205
0
         return false;
2206
0
      }
2207
0
      if(*m_position == charT('R'))
2208
0
      {
2209
0
         if(++m_position == m_end)
2210
0
         {
2211
            // Rewind to start of (? sequence:
2212
0
            --m_position;
2213
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2214
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2215
0
            return false;
2216
0
         }
2217
0
         if(*m_position == charT('&'))
2218
0
         {
2219
0
            const charT* base = ++m_position;
2220
0
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2221
0
               ++m_position;
2222
0
            if(m_position == m_end)
2223
0
            {
2224
               // Rewind to start of (? sequence:
2225
0
               --m_position;
2226
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2227
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2228
0
               return false;
2229
0
            }
2230
0
            v = -static_cast<int>(hash_value_from_capture_name(base, m_position));
2231
0
         }
2232
0
         else
2233
0
         {
2234
0
            v = -this->m_traits.toi(m_position, m_end, 10);
2235
0
         }
2236
0
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2237
0
         br->index = v < 0 ? (int)(v - 1) : 0;
2238
0
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2239
0
         {
2240
            // Rewind to start of (? sequence:
2241
0
            --m_position;
2242
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2243
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2244
0
            return false;
2245
0
         }
2246
0
         if(++m_position == m_end)
2247
0
         {
2248
            // Rewind to start of (? sequence:
2249
0
            --m_position;
2250
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2251
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2252
0
            return false;
2253
0
         }
2254
0
      }
2255
0
      else if((*m_position == charT('\'')) || (*m_position == charT('<')))
2256
0
      {
2257
0
         const charT* base = ++m_position;
2258
0
         while((m_position != m_end) && (*m_position != charT('>')) && (*m_position != charT('\'')))
2259
0
            ++m_position;
2260
0
         if(m_position == m_end)
2261
0
         {
2262
            // Rewind to start of (? sequence:
2263
0
            --m_position;
2264
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2265
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2266
0
            return false;
2267
0
         }
2268
0
         v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2269
0
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2270
0
         br->index = (int)v;
2271
0
         if(((*m_position != charT('>')) && (*m_position != charT('\''))) || (++m_position == m_end))
2272
0
         {
2273
            // Rewind to start of (? sequence:
2274
0
            --m_position;
2275
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2276
0
            fail(regex_constants::error_perl_extension, m_position - m_base, "Unterminated named capture.");
2277
0
            return false;
2278
0
         }
2279
0
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2280
0
         {
2281
            // Rewind to start of (? sequence:
2282
0
            --m_position;
2283
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2284
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2285
0
            return false;
2286
0
         }
2287
0
         if(++m_position == m_end)
2288
0
         {
2289
            // Rewind to start of (? sequence:
2290
0
            --m_position;
2291
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2292
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2293
0
            return false;
2294
0
         }
2295
0
      }
2296
0
      else if(*m_position == charT('D'))
2297
0
      {
2298
0
         const char* def = "DEFINE";
2299
0
         while(*def && (m_position != m_end) && (*m_position == charT(*def)))
2300
0
            ++m_position, ++def;
2301
0
         if((m_position == m_end) || *def)
2302
0
         {
2303
            // Rewind to start of (? sequence:
2304
0
            --m_position;
2305
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2306
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2307
0
            return false;
2308
0
         }
2309
0
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2310
0
         br->index = 9999; // special magic value!
2311
0
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2312
0
         {
2313
            // Rewind to start of (? sequence:
2314
0
            --m_position;
2315
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2316
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2317
0
            return false;
2318
0
         }
2319
0
         if(++m_position == m_end)
2320
0
         {
2321
            // Rewind to start of (? sequence:
2322
0
            --m_position;
2323
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2324
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2325
0
            return false;
2326
0
         }
2327
0
      }
2328
0
      else if(v > 0)
2329
0
      {
2330
0
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2331
0
         br->index = (int)v;
2332
0
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2333
0
         {
2334
            // Rewind to start of (? sequence:
2335
0
            --m_position;
2336
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2337
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2338
0
            return false;
2339
0
         }
2340
0
         if(++m_position == m_end)
2341
0
         {
2342
            // Rewind to start of (? sequence:
2343
0
            --m_position;
2344
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2345
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2346
0
            return false;
2347
0
         }
2348
0
      }
2349
0
      else
2350
0
      {
2351
         // verify that we have a lookahead or lookbehind assert:
2352
0
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_question)
2353
0
         {
2354
            // Rewind to start of (? sequence:
2355
0
            --m_position;
2356
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2357
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2358
0
            return false;
2359
0
         }
2360
0
         if(++m_position == m_end)
2361
0
         {
2362
            // Rewind to start of (? sequence:
2363
0
            --m_position;
2364
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2365
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2366
0
            return false;
2367
0
         }
2368
0
         if(this->m_traits.syntax_type(*m_position) == regex_constants::escape_type_left_word)
2369
0
         {
2370
0
            if(++m_position == m_end)
2371
0
            {
2372
               // Rewind to start of (? sequence:
2373
0
               --m_position;
2374
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2375
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2376
0
               return false;
2377
0
            }
2378
0
            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
2379
0
               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
2380
0
            {
2381
               // Rewind to start of (? sequence:
2382
0
               --m_position;
2383
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2384
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2385
0
               return false;
2386
0
            }
2387
0
            m_position -= 3;
2388
0
         }
2389
0
         else
2390
0
         {
2391
0
            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
2392
0
               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
2393
0
            {
2394
               // Rewind to start of (? sequence:
2395
0
               --m_position;
2396
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2397
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2398
0
               return false;
2399
0
            }
2400
0
            m_position -= 2;
2401
0
         }
2402
0
      }
2403
0
      break;
2404
0
      }
2405
0
   case regex_constants::syntax_close_mark:
2406
      // Rewind to start of (? sequence:
2407
0
      --m_position;
2408
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2409
0
      fail(regex_constants::error_perl_extension, m_position - m_base);
2410
0
      return false;
2411
0
   case regex_constants::escape_type_end_buffer:
2412
0
      {
2413
0
      name_delim = *m_position;
2414
0
named_capture_jump:
2415
0
      markid = 0;
2416
0
      if(0 == (this->flags() & regbase::nosubs))
2417
0
      {
2418
0
         markid = ++m_mark_count;
2419
0
         if(this->flags() & regbase::save_subexpression_location)
2420
0
            this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 2, 0));
2421
0
      }
2422
0
      pb->index = markid;
2423
0
      const charT* base = ++m_position;
2424
0
      if(m_position == m_end)
2425
0
      {
2426
         // Rewind to start of (? sequence:
2427
0
         --m_position;
2428
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2429
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2430
0
         return false;
2431
0
      }
2432
0
      while((m_position != m_end) && (*m_position != name_delim))
2433
0
         ++m_position;
2434
0
      if(m_position == m_end)
2435
0
      {
2436
         // Rewind to start of (? sequence:
2437
0
         --m_position;
2438
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2439
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2440
0
         return false;
2441
0
      }
2442
0
      this->m_pdata->set_name(base, m_position, markid);
2443
0
      ++m_position;
2444
0
      break;
2445
0
      }
2446
0
   default:
2447
0
      if(*m_position == charT('R'))
2448
0
      {
2449
0
         ++m_position;
2450
0
         v = 0;
2451
0
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2452
0
         {
2453
            // Rewind to start of (? sequence:
2454
0
            --m_position;
2455
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2456
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2457
0
            return false;
2458
0
         }
2459
0
         goto insert_recursion;
2460
0
      }
2461
0
      if(*m_position == charT('&'))
2462
0
      {
2463
0
         ++m_position;
2464
0
         const charT* base = m_position;
2465
0
         while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2466
0
            ++m_position;
2467
0
         if(m_position == m_end)
2468
0
         {
2469
            // Rewind to start of (? sequence:
2470
0
            --m_position;
2471
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2472
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2473
0
            return false;
2474
0
         }
2475
0
         v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2476
0
         goto insert_recursion;
2477
0
      }
2478
0
      if(*m_position == charT('P'))
2479
0
      {
2480
0
         ++m_position;
2481
0
         if(m_position == m_end)
2482
0
         {
2483
            // Rewind to start of (? sequence:
2484
0
            --m_position;
2485
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2486
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2487
0
            return false;
2488
0
         }
2489
0
         if(*m_position == charT('>'))
2490
0
         {
2491
0
            ++m_position;
2492
0
            const charT* base = m_position;
2493
0
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2494
0
               ++m_position;
2495
0
            if(m_position == m_end)
2496
0
            {
2497
               // Rewind to start of (? sequence:
2498
0
               --m_position;
2499
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2500
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2501
0
               return false;
2502
0
            }
2503
0
            v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2504
0
            goto insert_recursion;
2505
0
         }
2506
0
      }
2507
      //
2508
      // lets assume that we have a (?imsx) group and try and parse it:
2509
      //
2510
0
option_group_jump:
2511
0
      regex_constants::syntax_option_type opts = parse_options();
2512
0
      if(m_position == m_end)
2513
0
      {
2514
         // Rewind to start of (? sequence:
2515
0
         --m_position;
2516
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2517
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2518
0
         return false;
2519
0
      }
2520
      // make a note of whether we have a case change:
2521
0
      m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));
2522
0
      pb->index = markid = 0;
2523
0
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark)
2524
0
      {
2525
         // update flags and carry on as normal:
2526
0
         this->flags(opts);
2527
0
         restore_flags = false;
2528
0
         old_case_change |= m_has_case_change; // defer end of scope by one ')'
2529
0
      }
2530
0
      else if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_colon)
2531
0
      {
2532
         // update flags and carry on until the matching ')' is found:
2533
0
         this->flags(opts);
2534
0
         ++m_position;
2535
0
      }
2536
0
      else
2537
0
      {
2538
         // Rewind to start of (? sequence:
2539
0
         --m_position;
2540
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2541
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2542
0
         return false;
2543
0
      }
2544
2545
      // finally append a case change state if we need it:
2546
0
      if(m_has_case_change)
2547
0
      {
2548
0
         static_cast<re_case*>(
2549
0
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2550
0
            )->icase = opts & regbase::icase;
2551
0
      }
2552
2553
0
   }
2554
   //
2555
   // now recursively add more states, this will terminate when we get to a
2556
   // matching ')' :
2557
   //
2558
0
   parse_all();
2559
   //
2560
   // Unwind alternatives:
2561
   //
2562
0
   if(0 == unwind_alts(last_paren_start))
2563
0
   {
2564
      // Rewind to start of (? sequence:
2565
0
      --m_position;
2566
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2567
0
      fail(regex_constants::error_perl_extension, m_position - m_base, "Invalid alternation operators within (?...) block.");
2568
0
      return false;
2569
0
   }
2570
   //
2571
   // we either have a ')' or we have run out of characters prematurely:
2572
   //
2573
0
   if(m_position == m_end)
2574
0
   {
2575
      // Rewind to start of (? sequence:
2576
0
      --m_position;
2577
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2578
0
      this->fail(regex_constants::error_paren, std::distance(m_base, m_end));
2579
0
      return false;
2580
0
   }
2581
0
   BOOST_REGEX_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
2582
0
   ++m_position;
2583
   //
2584
   // restore the flags:
2585
   //
2586
0
   if(restore_flags)
2587
0
   {
2588
      // append a case change state if we need it:
2589
0
      if(m_has_case_change)
2590
0
      {
2591
0
         static_cast<re_case*>(
2592
0
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2593
0
            )->icase = old_flags & regbase::icase;
2594
0
      }
2595
0
      this->flags(old_flags);
2596
0
   }
2597
   //
2598
   // set up the jump pointer if we have one:
2599
   //
2600
0
   if(jump_offset)
2601
0
   {
2602
0
      this->m_pdata->m_data.align();
2603
0
      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
2604
0
      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
2605
0
      if((this->m_last_state == jmp) && (markid != -2))
2606
0
      {
2607
         // Oops... we didn't have anything inside the assertion.
2608
         // Note we don't get here for negated forward lookahead as (?!)
2609
         // does have some uses.
2610
         // Rewind to start of (? sequence:
2611
0
         --m_position;
2612
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2613
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "Invalid or empty zero width assertion.");
2614
0
         return false;
2615
0
      }
2616
0
   }
2617
   //
2618
   // verify that if this is conditional expression, that we do have
2619
   // an alternative, if not add one:
2620
   //
2621
0
   if(markid == -4)
2622
0
   {
2623
0
      re_syntax_base* b = this->getaddress(expected_alt_point);
2624
      // Make sure we have exactly one alternative following this state:
2625
0
      if(b->type != syntax_element_alt)
2626
0
      {
2627
0
         re_alt* alt = static_cast<re_alt*>(this->insert_state(expected_alt_point, syntax_element_alt, sizeof(re_alt)));
2628
0
         alt->alt.i = this->m_pdata->m_data.size() - this->getoffset(alt);
2629
0
      }
2630
0
      else if(((std::ptrdiff_t)this->m_pdata->m_data.size() > (static_cast<re_alt*>(b)->alt.i + this->getoffset(b))) && (static_cast<re_alt*>(b)->alt.i > 0) && this->getaddress(static_cast<re_alt*>(b)->alt.i, b)->type == syntax_element_alt)
2631
0
      {
2632
         // Can't have seen more than one alternative:
2633
         // Rewind to start of (? sequence:
2634
0
         --m_position;
2635
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2636
0
         fail(regex_constants::error_bad_pattern, m_position - m_base, "More than one alternation operator | was encountered inside a conditional expression.");
2637
0
         return false;
2638
0
      }
2639
0
      else
2640
0
      {
2641
         // We must *not* have seen an alternative inside a (DEFINE) block:
2642
0
         b = this->getaddress(b->next.i, b);
2643
0
         if((b->type == syntax_element_assert_backref) && (static_cast<re_brace*>(b)->index == 9999))
2644
0
         {
2645
            // Rewind to start of (? sequence:
2646
0
            --m_position;
2647
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2648
0
            fail(regex_constants::error_bad_pattern, m_position - m_base, "Alternation operators are not allowed inside a DEFINE block.");
2649
0
            return false;
2650
0
         }
2651
0
      }
2652
      // check for invalid repetition of next state:
2653
0
      b = this->getaddress(expected_alt_point);
2654
0
      b = this->getaddress(static_cast<re_alt*>(b)->next.i, b);
2655
0
      if((b->type != syntax_element_assert_backref)
2656
0
         && (b->type != syntax_element_startmark))
2657
0
      {
2658
         // Rewind to start of (? sequence:
2659
0
         --m_position;
2660
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2661
0
         fail(regex_constants::error_badrepeat, m_position - m_base, "A repetition operator cannot be applied to a zero-width assertion.");
2662
0
         return false;
2663
0
      }
2664
0
   }
2665
   //
2666
   // append closing parenthesis state:
2667
   //
2668
0
   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
2669
0
   pb->index = markid;
2670
0
   pb->icase = this->flags() & regbase::icase;
2671
0
   this->m_paren_start = last_paren_start;
2672
   //
2673
   // restore the alternate insertion point:
2674
   //
2675
0
   this->m_alt_insert_point = last_alt_point;
2676
   //
2677
   // and the case change data:
2678
   //
2679
0
   m_has_case_change = old_case_change;
2680
   //
2681
   // And the mark_reset data:
2682
   //
2683
0
   if(m_max_mark > m_mark_count)
2684
0
   {
2685
0
      m_mark_count = m_max_mark;
2686
0
   }
2687
0
   m_mark_reset = mark_reset;
2688
0
   m_max_mark = max_mark;
2689
2690
2691
0
   if(markid > 0)
2692
0
   {
2693
0
      if(this->flags() & regbase::save_subexpression_location)
2694
0
         this->m_pdata->m_subs.at((std::size_t)markid - 1).second = std::distance(m_base, m_position) - 1;
2695
      //
2696
      // allow backrefs to this mark:
2697
      //
2698
0
      this->m_backrefs.set(markid);
2699
0
   }
2700
0
   return true;
2701
0
}
2702
2703
template <class charT, class traits>
2704
bool basic_regex_parser<charT, traits>::match_verb(const char* verb)
2705
0
{
2706
0
   while(*verb)
2707
0
   {
2708
0
      if(static_cast<charT>(*verb) != *m_position)
2709
0
      {
2710
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2711
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2712
0
         return false;
2713
0
      }
2714
0
      if(++m_position == m_end)
2715
0
      {
2716
0
         --m_position;
2717
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2718
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2719
0
         return false;
2720
0
      }
2721
0
      ++verb;
2722
0
   }
2723
0
   return true;
2724
0
}
2725
2726
#ifdef BOOST_REGEX_MSVC
2727
#  pragma warning(push)
2728
#if BOOST_REGEX_MSVC >= 1800
2729
#pragma warning(disable:26812)
2730
#endif
2731
#endif
2732
template <class charT, class traits>
2733
bool basic_regex_parser<charT, traits>::parse_perl_verb()
2734
0
{
2735
0
   if(++m_position == m_end)
2736
0
   {
2737
      // Rewind to start of (* sequence:
2738
0
      --m_position;
2739
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2740
0
      fail(regex_constants::error_perl_extension, m_position - m_base);
2741
0
      return false;
2742
0
   }
2743
0
   switch(*m_position)
2744
0
   {
2745
0
   case 'F':
2746
0
      if(++m_position == m_end)
2747
0
      {
2748
         // Rewind to start of (* sequence:
2749
0
         --m_position;
2750
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2751
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2752
0
         return false;
2753
0
      }
2754
0
      if((this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark) || match_verb("AIL"))
2755
0
      {
2756
0
         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2757
0
         {
2758
            // Rewind to start of (* sequence:
2759
0
            --m_position;
2760
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2761
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2762
0
            return false;
2763
0
         }
2764
0
         ++m_position;
2765
0
         this->append_state(syntax_element_fail);
2766
0
         return true;
2767
0
      }
2768
0
      break;
2769
0
   case 'A':
2770
0
      if(++m_position == m_end)
2771
0
      {
2772
         // Rewind to start of (* sequence:
2773
0
         --m_position;
2774
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2775
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2776
0
         return false;
2777
0
      }
2778
0
      if(match_verb("CCEPT"))
2779
0
      {
2780
0
         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2781
0
         {
2782
            // Rewind to start of (* sequence:
2783
0
            --m_position;
2784
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2785
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2786
0
            return false;
2787
0
         }
2788
0
         ++m_position;
2789
0
         this->append_state(syntax_element_accept);
2790
0
         return true;
2791
0
      }
2792
0
      break;
2793
0
   case 'C':
2794
0
      if(++m_position == m_end)
2795
0
      {
2796
         // Rewind to start of (* sequence:
2797
0
         --m_position;
2798
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2799
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2800
0
         return false;
2801
0
      }
2802
0
      if(match_verb("OMMIT"))
2803
0
      {
2804
0
         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2805
0
         {
2806
            // Rewind to start of (* sequence:
2807
0
            --m_position;
2808
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2809
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2810
0
            return false;
2811
0
         }
2812
0
         ++m_position;
2813
0
         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_commit;
2814
0
         this->m_pdata->m_disable_match_any = true;
2815
0
         return true;
2816
0
      }
2817
0
      break;
2818
0
   case 'P':
2819
0
      if(++m_position == m_end)
2820
0
      {
2821
         // Rewind to start of (* sequence:
2822
0
         --m_position;
2823
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2824
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2825
0
         return false;
2826
0
      }
2827
0
      if(match_verb("RUNE"))
2828
0
      {
2829
0
         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2830
0
         {
2831
            // Rewind to start of (* sequence:
2832
0
            --m_position;
2833
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2834
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2835
0
            return false;
2836
0
         }
2837
0
         ++m_position;
2838
0
         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_prune;
2839
0
         this->m_pdata->m_disable_match_any = true;
2840
0
         return true;
2841
0
      }
2842
0
      break;
2843
0
   case 'S':
2844
0
      if(++m_position == m_end)
2845
0
      {
2846
         // Rewind to start of (* sequence:
2847
0
         --m_position;
2848
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2849
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2850
0
         return false;
2851
0
      }
2852
0
      if(match_verb("KIP"))
2853
0
      {
2854
0
         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2855
0
         {
2856
            // Rewind to start of (* sequence:
2857
0
            --m_position;
2858
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2859
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2860
0
            return false;
2861
0
         }
2862
0
         ++m_position;
2863
0
         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_skip;
2864
0
         this->m_pdata->m_disable_match_any = true;
2865
0
         return true;
2866
0
      }
2867
0
      break;
2868
0
   case 'T':
2869
0
      if(++m_position == m_end)
2870
0
      {
2871
         // Rewind to start of (* sequence:
2872
0
         --m_position;
2873
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2874
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2875
0
         return false;
2876
0
      }
2877
0
      if(match_verb("HEN"))
2878
0
      {
2879
0
         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2880
0
         {
2881
            // Rewind to start of (* sequence:
2882
0
            --m_position;
2883
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2884
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2885
0
            return false;
2886
0
         }
2887
0
         ++m_position;
2888
0
         this->append_state(syntax_element_then);
2889
0
         this->m_pdata->m_disable_match_any = true;
2890
0
         return true;
2891
0
      }
2892
0
      break;
2893
0
   }
2894
   // Rewind to start of (* sequence:
2895
0
   --m_position;
2896
0
   while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2897
0
   fail(regex_constants::error_perl_extension, m_position - m_base);
2898
0
   return false;
2899
0
}
2900
#ifdef BOOST_REGEX_MSVC
2901
#  pragma warning(pop)
2902
#endif
2903
2904
template <class charT, class traits>
2905
bool basic_regex_parser<charT, traits>::add_emacs_code(bool negate)
2906
0
{
2907
   //
2908
   // parses an emacs style \sx or \Sx construct.
2909
   //
2910
0
   if(++m_position == m_end)
2911
0
   {
2912
      // Rewind to start of sequence:
2913
0
      --m_position;
2914
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
2915
0
      fail(regex_constants::error_escape, m_position - m_base);
2916
0
      return false;
2917
0
   }
2918
0
   basic_char_set<charT, traits> char_set;
2919
0
   if(negate)
2920
0
      char_set.negate();
2921
2922
0
   static const charT s_punct[5] = { 'p', 'u', 'n', 'c', 't', };
2923
2924
0
   switch(*m_position)
2925
0
   {
2926
0
   case 's':
2927
0
   case ' ':
2928
0
      char_set.add_class(this->m_mask_space);
2929
0
      break;
2930
0
   case 'w':
2931
0
      char_set.add_class(this->m_word_mask);
2932
0
      break;
2933
0
   case '_':
2934
0
      char_set.add_single(digraph<charT>(charT('$'))); 
2935
0
      char_set.add_single(digraph<charT>(charT('&'))); 
2936
0
      char_set.add_single(digraph<charT>(charT('*'))); 
2937
0
      char_set.add_single(digraph<charT>(charT('+'))); 
2938
0
      char_set.add_single(digraph<charT>(charT('-'))); 
2939
0
      char_set.add_single(digraph<charT>(charT('_'))); 
2940
0
      char_set.add_single(digraph<charT>(charT('<'))); 
2941
0
      char_set.add_single(digraph<charT>(charT('>'))); 
2942
0
      break;
2943
0
   case '.':
2944
0
      char_set.add_class(this->m_traits.lookup_classname(s_punct, s_punct+5));
2945
0
      break;
2946
0
   case '(':
2947
0
      char_set.add_single(digraph<charT>(charT('('))); 
2948
0
      char_set.add_single(digraph<charT>(charT('['))); 
2949
0
      char_set.add_single(digraph<charT>(charT('{'))); 
2950
0
      break;
2951
0
   case ')':
2952
0
      char_set.add_single(digraph<charT>(charT(')'))); 
2953
0
      char_set.add_single(digraph<charT>(charT(']'))); 
2954
0
      char_set.add_single(digraph<charT>(charT('}'))); 
2955
0
      break;
2956
0
   case '"':
2957
0
      char_set.add_single(digraph<charT>(charT('"'))); 
2958
0
      char_set.add_single(digraph<charT>(charT('\''))); 
2959
0
      char_set.add_single(digraph<charT>(charT('`'))); 
2960
0
      break;
2961
0
   case '\'':
2962
0
      char_set.add_single(digraph<charT>(charT('\''))); 
2963
0
      char_set.add_single(digraph<charT>(charT(','))); 
2964
0
      char_set.add_single(digraph<charT>(charT('#'))); 
2965
0
      break;
2966
0
   case '<':
2967
0
      char_set.add_single(digraph<charT>(charT(';'))); 
2968
0
      break;
2969
0
   case '>':
2970
0
      char_set.add_single(digraph<charT>(charT('\n'))); 
2971
0
      char_set.add_single(digraph<charT>(charT('\f'))); 
2972
0
      break;
2973
0
   default:
2974
0
      fail(regex_constants::error_ctype, m_position - m_base);
2975
0
      return false;
2976
0
   }
2977
0
   if(0 == this->append_set(char_set))
2978
0
   {
2979
0
      fail(regex_constants::error_ctype, m_position - m_base);
2980
0
      return false;
2981
0
   }
2982
0
   ++m_position;
2983
0
   return true;
2984
0
}
2985
2986
template <class charT, class traits>
2987
regex_constants::syntax_option_type basic_regex_parser<charT, traits>::parse_options()
2988
0
{
2989
   // we have a (?imsx-imsx) group, convert it into a set of flags:
2990
0
   regex_constants::syntax_option_type f = this->flags();
2991
0
   bool breakout = false;
2992
0
   do
2993
0
   {
2994
0
      switch(*m_position)
2995
0
      {
2996
0
      case 's':
2997
0
         f |= regex_constants::mod_s;
2998
0
         f &= ~regex_constants::no_mod_s;
2999
0
         break;
3000
0
      case 'm':
3001
0
         f &= ~regex_constants::no_mod_m;
3002
0
         break;
3003
0
      case 'i':
3004
0
         f |= regex_constants::icase;
3005
0
         break;
3006
0
      case 'x':
3007
0
         f |= regex_constants::mod_x;
3008
0
         break;
3009
0
      default:
3010
0
         breakout = true;
3011
0
         continue;
3012
0
      }
3013
0
      if(++m_position == m_end)
3014
0
      {
3015
         // Rewind to start of (? sequence:
3016
0
         --m_position;
3017
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
3018
0
         fail(regex_constants::error_paren, m_position - m_base);
3019
0
         return false;
3020
0
      }
3021
0
   }
3022
0
   while(!breakout);
3023
   
3024
0
   breakout = false;
3025
3026
0
   if(*m_position == static_cast<charT>('-'))
3027
0
   {
3028
0
      if(++m_position == m_end)
3029
0
      {
3030
         // Rewind to start of (? sequence:
3031
0
         --m_position;
3032
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
3033
0
         fail(regex_constants::error_paren, m_position - m_base);
3034
0
         return false;
3035
0
      }
3036
0
      do
3037
0
      {
3038
0
         switch(*m_position)
3039
0
         {
3040
0
         case 's':
3041
0
            f &= ~regex_constants::mod_s;
3042
0
            f |= regex_constants::no_mod_s;
3043
0
            break;
3044
0
         case 'm':
3045
0
            f |= regex_constants::no_mod_m;
3046
0
            break;
3047
0
         case 'i':
3048
0
            f &= ~regex_constants::icase;
3049
0
            break;
3050
0
         case 'x':
3051
0
            f &= ~regex_constants::mod_x;
3052
0
            break;
3053
0
         default:
3054
0
            breakout = true;
3055
0
            continue;
3056
0
         }
3057
0
         if(++m_position == m_end)
3058
0
         {
3059
            // Rewind to start of (? sequence:
3060
0
            --m_position;
3061
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
3062
0
            fail(regex_constants::error_paren, m_position - m_base);
3063
0
            return false;
3064
0
         }
3065
0
      }
3066
0
      while(!breakout);
3067
0
   }
3068
0
   return f;
3069
0
}
3070
3071
template <class charT, class traits>
3072
bool basic_regex_parser<charT, traits>::unwind_alts(std::ptrdiff_t last_paren_start)
3073
10
{
3074
   //
3075
   // If we didn't actually add any states after the last 
3076
   // alternative then that's an error:
3077
   //
3078
10
   if((this->m_alt_insert_point == static_cast<std::ptrdiff_t>(this->m_pdata->m_data.size()))
3079
10
      && (!m_alt_jumps.empty()) && (m_alt_jumps.back() > last_paren_start)
3080
10
      &&
3081
10
      !(
3082
0
         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)
3083
0
           &&
3084
0
         ((this->flags() & regbase::no_empty_expressions) == 0)
3085
0
        )
3086
10
      )
3087
0
   {
3088
0
      fail(regex_constants::error_empty, this->m_position - this->m_base, "Can't terminate a sub-expression with an alternation operator |.");
3089
0
      return false;
3090
0
   }
3091
   // 
3092
   // Fix up our alternatives:
3093
   //
3094
10
   while((!m_alt_jumps.empty()) && (m_alt_jumps.back() > last_paren_start))
3095
0
   {
3096
      //
3097
      // fix up the jump to point to the end of the states
3098
      // that we've just added:
3099
      //
3100
0
      std::ptrdiff_t jump_offset = m_alt_jumps.back();
3101
0
      m_alt_jumps.pop_back();
3102
0
      this->m_pdata->m_data.align();
3103
0
      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
3104
0
      BOOST_REGEX_ASSERT(jmp->type == syntax_element_jump);
3105
0
      jmp->alt.i = this->m_pdata->m_data.size() - jump_offset;
3106
0
   }
3107
10
   return true;
3108
10
}
3109
3110
#ifdef BOOST_REGEX_MSVC
3111
#pragma warning(pop)
3112
#endif
3113
3114
} // namespace BOOST_REGEX_DETAIL_NS
3115
} // namespace boost
3116
3117
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/c_regex_traits.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2004
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
 
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         c_regex_traits.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares regular expression traits class that wraps the global C locale.
17
  */
18
19
#ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED
20
#define BOOST_C_REGEX_TRAITS_HPP_INCLUDED
21
22
#include <boost/regex/config.hpp>
23
#include <boost/regex/v5/regex_workaround.hpp>
24
#include <cctype>
25
26
namespace boost{
27
28
   namespace BOOST_REGEX_DETAIL_NS {
29
30
      enum
31
      {
32
         char_class_space = 1 << 0,
33
         char_class_print = 1 << 1,
34
         char_class_cntrl = 1 << 2,
35
         char_class_upper = 1 << 3,
36
         char_class_lower = 1 << 4,
37
         char_class_alpha = 1 << 5,
38
         char_class_digit = 1 << 6,
39
         char_class_punct = 1 << 7,
40
         char_class_xdigit = 1 << 8,
41
         char_class_alnum = char_class_alpha | char_class_digit,
42
         char_class_graph = char_class_alnum | char_class_punct,
43
         char_class_blank = 1 << 9,
44
         char_class_word = 1 << 10,
45
         char_class_unicode = 1 << 11,
46
         char_class_horizontal = 1 << 12,
47
         char_class_vertical = 1 << 13
48
      };
49
50
   }
51
52
template <class charT>
53
struct c_regex_traits;
54
55
template<>
56
struct c_regex_traits<char>
57
{
58
0
   c_regex_traits(){}
59
   typedef char char_type;
60
   typedef std::size_t size_type;
61
   typedef std::string string_type;
62
   struct locale_type{};
63
   typedef std::uint32_t char_class_type;
64
65
   static size_type length(const char_type* p) 
66
0
   { 
67
0
      return (std::strlen)(p); 
68
0
   }
69
70
   char translate(char c) const 
71
0
   { 
72
0
      return c; 
73
0
   }
74
   char translate_nocase(char c) const 
75
0
   { 
76
0
      return static_cast<char>((std::tolower)(static_cast<unsigned char>(c))); 
77
0
   }
78
79
   static string_type  transform(const char* p1, const char* p2);
80
   static string_type  transform_primary(const char* p1, const char* p2);
81
82
   static char_class_type  lookup_classname(const char* p1, const char* p2);
83
   static string_type  lookup_collatename(const char* p1, const char* p2);
84
85
   static bool  isctype(char, char_class_type);
86
   static int  value(char, int);
87
88
   locale_type imbue(locale_type l)
89
0
   { return l; }
90
   locale_type getloc()const
91
0
   { return locale_type(); }
92
93
private:
94
   // this type is not copyable:
95
   c_regex_traits(const c_regex_traits&);
96
   c_regex_traits& operator=(const c_regex_traits&);
97
};
98
99
#ifndef BOOST_NO_WREGEX
100
template<>
101
struct c_regex_traits<wchar_t>
102
{
103
0
   c_regex_traits(){}
104
   typedef wchar_t char_type;
105
   typedef std::size_t size_type;
106
   typedef std::wstring string_type;
107
   struct locale_type{};
108
   typedef std::uint32_t char_class_type;
109
110
   static size_type length(const char_type* p) 
111
0
   { 
112
0
      return (std::wcslen)(p); 
113
0
   }
114
115
   wchar_t translate(wchar_t c) const 
116
0
   { 
117
0
      return c; 
118
0
   }
119
   wchar_t translate_nocase(wchar_t c) const 
120
0
   { 
121
0
      return (std::towlower)(c); 
122
0
   }
123
124
   static string_type  transform(const wchar_t* p1, const wchar_t* p2);
125
   static string_type  transform_primary(const wchar_t* p1, const wchar_t* p2);
126
127
   static char_class_type  lookup_classname(const wchar_t* p1, const wchar_t* p2);
128
   static string_type  lookup_collatename(const wchar_t* p1, const wchar_t* p2);
129
130
   static bool  isctype(wchar_t, char_class_type);
131
   static int  value(wchar_t, int);
132
133
   locale_type imbue(locale_type l)
134
0
   { return l; }
135
   locale_type getloc()const
136
0
   { return locale_type(); }
137
138
private:
139
   // this type is not copyable:
140
   c_regex_traits(const c_regex_traits&);
141
   c_regex_traits& operator=(const c_regex_traits&);
142
};
143
144
#endif // BOOST_NO_WREGEX
145
146
inline c_regex_traits<char>::string_type  c_regex_traits<char>::transform(const char* p1, const char* p2)
147
0
{
148
0
   std::string result(10, ' ');
149
0
   std::size_t s = result.size();
150
0
   std::size_t r;
151
0
   std::string src(p1, p2);
152
0
   while (s < (r = std::strxfrm(&*result.begin(), src.c_str(), s)))
153
0
   {
154
0
#if defined(_CPPLIB_VER)
155
0
      //
156
0
      // A bug in VC11 and 12 causes the program to hang if we pass a null-string
157
0
      // to std::strxfrm, but only for certain locales :-(
158
0
      // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
159
0
      //
160
0
      if (r == INT_MAX)
161
0
      {
162
0
         result.erase();
163
0
         result.insert(result.begin(), static_cast<char>(0));
164
0
         return result;
165
0
      }
166
0
#endif
167
0
      result.append(r - s + 3, ' ');
168
0
      s = result.size();
169
0
   }
170
0
   result.erase(r);
171
0
   return result;
172
0
}
173
174
inline c_regex_traits<char>::string_type  c_regex_traits<char>::transform_primary(const char* p1, const char* p2)
175
0
{
176
0
   static char s_delim;
177
0
   static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<c_regex_traits<char>*>(0), &s_delim);
178
0
   std::string result;
179
0
   //
180
0
   // What we do here depends upon the format of the sort key returned by
181
0
   // sort key returned by this->transform:
182
0
   //
183
0
   switch (s_collate_type)
184
0
   {
185
0
   case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:
186
0
   case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:
187
0
      // the best we can do is translate to lower case, then get a regular sort key:
188
0
   {
189
0
      result.assign(p1, p2);
190
0
      for (std::string::size_type i = 0; i < result.size(); ++i)
191
0
         result[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(result[i])));
192
0
      result = transform(&*result.begin(), &*result.begin() + result.size());
193
0
      break;
194
0
   }
195
0
   case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:
196
0
   {
197
0
      // get a regular sort key, and then truncate it:
198
0
      result = transform(p1, p2);
199
0
      result.erase(s_delim);
200
0
      break;
201
0
   }
202
0
   case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:
203
0
      // get a regular sort key, and then truncate everything after the delim:
204
0
      result = transform(p1, p2);
205
0
      if ((!result.empty()) && (result[0] == s_delim))
206
0
         break;
207
0
      std::size_t i;
208
0
      for (i = 0; i < result.size(); ++i)
209
0
      {
210
0
         if (result[i] == s_delim)
211
0
            break;
212
0
      }
213
0
      result.erase(i);
214
0
      break;
215
0
   }
216
0
   if (result.empty())
217
0
      result = std::string(1, char(0));
218
0
   return result;
219
0
}
220
221
inline c_regex_traits<char>::char_class_type  c_regex_traits<char>::lookup_classname(const char* p1, const char* p2)
222
0
{
223
0
   using namespace BOOST_REGEX_DETAIL_NS;
224
0
   static const char_class_type masks[] =
225
0
   {
226
0
      0,
227
0
      char_class_alnum,
228
0
      char_class_alpha,
229
0
      char_class_blank,
230
0
      char_class_cntrl,
231
0
      char_class_digit,
232
0
      char_class_digit,
233
0
      char_class_graph,
234
0
      char_class_horizontal,
235
0
      char_class_lower,
236
0
      char_class_lower,
237
0
      char_class_print,
238
0
      char_class_punct,
239
0
      char_class_space,
240
0
      char_class_space,
241
0
      char_class_upper,
242
0
      char_class_unicode,
243
0
      char_class_upper,
244
0
      char_class_vertical,
245
0
      char_class_alnum | char_class_word,
246
0
      char_class_alnum | char_class_word,
247
0
      char_class_xdigit,
248
0
   };
249
0
250
0
   int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);
251
0
   if (idx < 0)
252
0
   {
253
0
      std::string s(p1, p2);
254
0
      for (std::string::size_type i = 0; i < s.size(); ++i)
255
0
         s[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(s[i])));
256
0
      idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
257
0
   }
258
0
   BOOST_REGEX_ASSERT(std::size_t(idx) + 1u < sizeof(masks) / sizeof(masks[0]));
259
0
   return masks[idx + 1];
260
0
}
261
262
inline bool  c_regex_traits<char>::isctype(char c, char_class_type mask)
263
0
{
264
0
   using namespace BOOST_REGEX_DETAIL_NS;
265
0
   return
266
0
      ((mask & char_class_space) && (std::isspace)(static_cast<unsigned char>(c)))
267
0
      || ((mask & char_class_print) && (std::isprint)(static_cast<unsigned char>(c)))
268
0
      || ((mask & char_class_cntrl) && (std::iscntrl)(static_cast<unsigned char>(c)))
269
0
      || ((mask & char_class_upper) && (std::isupper)(static_cast<unsigned char>(c)))
270
0
      || ((mask & char_class_lower) && (std::islower)(static_cast<unsigned char>(c)))
271
0
      || ((mask & char_class_alpha) && (std::isalpha)(static_cast<unsigned char>(c)))
272
0
      || ((mask & char_class_digit) && (std::isdigit)(static_cast<unsigned char>(c)))
273
0
      || ((mask & char_class_punct) && (std::ispunct)(static_cast<unsigned char>(c)))
274
0
      || ((mask & char_class_xdigit) && (std::isxdigit)(static_cast<unsigned char>(c)))
275
0
      || ((mask & char_class_blank) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))
276
0
      || ((mask & char_class_word) && (c == '_'))
277
0
      || ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\v')))
278
0
      || ((mask & char_class_horizontal) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != '\v'));
279
0
}
280
281
inline c_regex_traits<char>::string_type  c_regex_traits<char>::lookup_collatename(const char* p1, const char* p2)
282
0
{
283
0
   std::string s(p1, p2);
284
0
   s = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(s);
285
0
   if (s.empty() && (p2 - p1 == 1))
286
0
      s.append(1, *p1);
287
0
   return s;
288
0
}
289
290
inline int  c_regex_traits<char>::value(char c, int radix)
291
0
{
292
0
   char b[2] = { c, '\0', };
293
0
   char* ep;
294
0
   int result = std::strtol(b, &ep, radix);
295
0
   if (ep == b)
296
0
      return -1;
297
0
   return result;
298
0
}
299
300
#ifndef BOOST_NO_WREGEX
301
302
inline c_regex_traits<wchar_t>::string_type  c_regex_traits<wchar_t>::transform(const wchar_t* p1, const wchar_t* p2)
303
0
{
304
0
   std::size_t r;
305
0
   std::size_t s = 10;
306
0
   std::wstring src(p1, p2);
307
0
   std::wstring result(s, L' ');
308
0
   while (s < (r = std::wcsxfrm(&*result.begin(), src.c_str(), s)))
309
0
   {
310
0
#if defined(_CPPLIB_VER)
311
0
      //
312
0
      // A bug in VC11 and 12 causes the program to hang if we pass a null-string
313
0
      // to std::strxfrm, but only for certain locales :-(
314
0
      // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
315
0
      //
316
0
      if (r == INT_MAX)
317
0
      {
318
0
         result.erase();
319
0
         result.insert(result.begin(), static_cast<wchar_t>(0));
320
0
         return result;
321
0
      }
322
0
#endif
323
0
      result.append(r - s + 3, L' ');
324
0
      s = result.size();
325
0
   }
326
0
   result.erase(r);
327
0
   return result;
328
0
}
329
330
inline c_regex_traits<wchar_t>::string_type  c_regex_traits<wchar_t>::transform_primary(const wchar_t* p1, const wchar_t* p2)
331
0
{
332
0
   static wchar_t s_delim;
333
0
   static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<const c_regex_traits<wchar_t>*>(0), &s_delim);
334
0
   std::wstring result;
335
0
   //
336
0
   // What we do here depends upon the format of the sort key returned by
337
0
   // sort key returned by this->transform:
338
0
   //
339
0
   switch (s_collate_type)
340
0
   {
341
0
   case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:
342
0
   case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:
343
0
      // the best we can do is translate to lower case, then get a regular sort key:
344
0
   {
345
0
      result.assign(p1, p2);
346
0
      for (std::wstring::size_type i = 0; i < result.size(); ++i)
347
0
         result[i] = (std::towlower)(result[i]);
348
0
      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());
349
0
      break;
350
0
   }
351
0
   case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:
352
0
   {
353
0
      // get a regular sort key, and then truncate it:
354
0
      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());
355
0
      result.erase(s_delim);
356
0
      break;
357
0
   }
358
0
   case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:
359
0
      // get a regular sort key, and then truncate everything after the delim:
360
0
      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());
361
0
      if ((!result.empty()) && (result[0] == s_delim))
362
0
         break;
363
0
      std::size_t i;
364
0
      for (i = 0; i < result.size(); ++i)
365
0
      {
366
0
         if (result[i] == s_delim)
367
0
            break;
368
0
      }
369
0
      result.erase(i);
370
0
      break;
371
0
   }
372
0
   if (result.empty())
373
0
      result = std::wstring(1, char(0));
374
0
   return result;
375
0
}
376
377
inline c_regex_traits<wchar_t>::char_class_type  c_regex_traits<wchar_t>::lookup_classname(const wchar_t* p1, const wchar_t* p2)
378
0
{
379
0
   using namespace BOOST_REGEX_DETAIL_NS;
380
0
   static const char_class_type masks[] =
381
0
   {
382
0
      0,
383
0
      char_class_alnum,
384
0
      char_class_alpha,
385
0
      char_class_blank,
386
0
      char_class_cntrl,
387
0
      char_class_digit,
388
0
      char_class_digit,
389
0
      char_class_graph,
390
0
      char_class_horizontal,
391
0
      char_class_lower,
392
0
      char_class_lower,
393
0
      char_class_print,
394
0
      char_class_punct,
395
0
      char_class_space,
396
0
      char_class_space,
397
0
      char_class_upper,
398
0
      char_class_unicode,
399
0
      char_class_upper,
400
0
      char_class_vertical,
401
0
      char_class_alnum | char_class_word,
402
0
      char_class_alnum | char_class_word,
403
0
      char_class_xdigit,
404
0
   };
405
0
406
0
   int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);
407
0
   if (idx < 0)
408
0
   {
409
0
      std::wstring s(p1, p2);
410
0
      for (std::wstring::size_type i = 0; i < s.size(); ++i)
411
0
         s[i] = (std::towlower)(s[i]);
412
0
      idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
413
0
   }
414
0
   BOOST_REGEX_ASSERT(idx + 1 < static_cast<int>(sizeof(masks) / sizeof(masks[0])));
415
0
   return masks[idx + 1];
416
0
}
417
418
inline bool  c_regex_traits<wchar_t>::isctype(wchar_t c, char_class_type mask)
419
0
{
420
0
   using namespace BOOST_REGEX_DETAIL_NS;
421
0
   return
422
0
      ((mask & char_class_space) && (std::iswspace)(c))
423
0
      || ((mask & char_class_print) && (std::iswprint)(c))
424
0
      || ((mask & char_class_cntrl) && (std::iswcntrl)(c))
425
0
      || ((mask & char_class_upper) && (std::iswupper)(c))
426
0
      || ((mask & char_class_lower) && (std::iswlower)(c))
427
0
      || ((mask & char_class_alpha) && (std::iswalpha)(c))
428
0
      || ((mask & char_class_digit) && (std::iswdigit)(c))
429
0
      || ((mask & char_class_punct) && (std::iswpunct)(c))
430
0
      || ((mask & char_class_xdigit) && (std::iswxdigit)(c))
431
0
      || ((mask & char_class_blank) && (std::iswspace)(c) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))
432
0
      || ((mask & char_class_word) && (c == '_'))
433
0
      || ((mask & char_class_unicode) && (c & ~static_cast<wchar_t>(0xff)))
434
0
      || ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == L'\v')))
435
0
      || ((mask & char_class_horizontal) && (std::iswspace)(c) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != L'\v'));
436
0
}
437
438
inline c_regex_traits<wchar_t>::string_type  c_regex_traits<wchar_t>::lookup_collatename(const wchar_t* p1, const wchar_t* p2)
439
0
{
440
0
   std::string name;
441
0
   // Usual msvc warning suppression does not work here with std::string template constructor.... use a workaround instead:
442
0
   for (const wchar_t* pos = p1; pos != p2; ++pos)
443
0
      name.push_back((char)*pos);
444
0
   name = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(name);
445
0
   if (!name.empty())
446
0
      return string_type(name.begin(), name.end());
447
0
   if (p2 - p1 == 1)
448
0
      return string_type(1, *p1);
449
0
   return string_type();
450
0
}
451
452
inline int  c_regex_traits<wchar_t>::value(wchar_t c, int radix)
453
0
{
454
0
#ifdef BOOST_BORLANDC
455
0
   // workaround for broken wcstol:
456
0
   if ((std::iswxdigit)(c) == 0)
457
0
      return -1;
458
0
#endif
459
0
   wchar_t b[2] = { c, '\0', };
460
0
   wchar_t* ep;
461
0
   int result = std::wcstol(b, &ep, radix);
462
0
   if (ep == b)
463
0
      return -1;
464
0
   return result;
465
0
}
466
467
#endif
468
469
}
470
471
#endif
472
473
474
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/cpp_regex_traits.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2004 John Maddock
4
 * Copyright 2011 Garmin Ltd. or its subsidiaries
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
 
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         cpp_regex_traits.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares regular expression traits class cpp_regex_traits.
17
  */
18
19
#ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
20
#define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
21
22
#include <boost/regex/config.hpp>
23
#include <cstdint>
24
#include <locale>
25
#include <type_traits>
26
27
#include <boost/regex/pattern_except.hpp>
28
#include <boost/regex/v5/regex_traits_defaults.hpp>
29
30
#ifdef BOOST_HAS_THREADS
31
#include <mutex>
32
#endif
33
#include <boost/regex/v5/primary_transform.hpp>
34
#include <boost/regex/v5/object_cache.hpp>
35
36
#include <climits>
37
#include <ios>
38
#include <istream>
39
40
#ifdef BOOST_REGEX_MSVC
41
#pragma warning(push)
42
#pragma warning(disable:4786 4251)
43
#endif
44
45
namespace boost{ 
46
47
//
48
// forward declaration is needed by some compilers:
49
//
50
template <class charT>
51
class cpp_regex_traits;
52
   
53
namespace BOOST_REGEX_DETAIL_NS{
54
55
//
56
// class parser_buf:
57
// acts as a stream buffer which wraps around a pair of pointers:
58
//
59
template <class charT,
60
          class traits = ::std::char_traits<charT> >
61
class parser_buf : public ::std::basic_streambuf<charT, traits>
62
{
63
   typedef ::std::basic_streambuf<charT, traits> base_type;
64
   typedef typename base_type::int_type int_type;
65
   typedef typename base_type::char_type char_type;
66
   typedef typename base_type::pos_type pos_type;
67
   typedef ::std::streamsize streamsize;
68
   typedef typename base_type::off_type off_type;
69
public:
70
0
   parser_buf() : base_type() { setbuf(0, 0); }
71
   const charT* getnext() { return this->gptr(); }
72
protected:
73
   std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n) override;
74
   typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) override;
75
   typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) override;
76
private:
77
   parser_buf& operator=(const parser_buf&);
78
   parser_buf(const parser_buf&);
79
};
80
81
template<class charT, class traits>
82
std::basic_streambuf<charT, traits>*
83
parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
84
0
{
85
0
   this->setg(s, s, s + n);
86
0
   return this;
87
0
}
88
89
template<class charT, class traits>
90
typename parser_buf<charT, traits>::pos_type
91
parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
92
0
{
93
0
   if(which & ::std::ios_base::out)
94
0
      return pos_type(off_type(-1));
95
0
   std::ptrdiff_t size = this->egptr() - this->eback();
96
0
   std::ptrdiff_t pos = this->gptr() - this->eback();
97
0
   charT* g = this->eback();
98
0
   switch(static_cast<std::intmax_t>(way))
99
0
   {
100
0
   case ::std::ios_base::beg:
101
0
      if((off < 0) || (off > size))
102
0
         return pos_type(off_type(-1));
103
0
      else
104
0
         this->setg(g, g + off, g + size);
105
0
      break;
106
0
   case ::std::ios_base::end:
107
0
      if((off < 0) || (off > size))
108
0
         return pos_type(off_type(-1));
109
0
      else
110
0
         this->setg(g, g + size - off, g + size);
111
0
      break;
112
0
   case ::std::ios_base::cur:
113
0
   {
114
0
      std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
115
0
      if((newpos < 0) || (newpos > size))
116
0
         return pos_type(off_type(-1));
117
0
      else
118
0
         this->setg(g, g + newpos, g + size);
119
0
      break;
120
0
   }
121
0
   default: ;
122
0
   }
123
#ifdef BOOST_REGEX_MSVC
124
#pragma warning(push)
125
#pragma warning(disable:4244)
126
#endif
127
0
   return static_cast<pos_type>(this->gptr() - this->eback());
128
#ifdef BOOST_REGEX_MSVC
129
#pragma warning(pop)
130
#endif
131
0
}
132
133
template<class charT, class traits>
134
typename parser_buf<charT, traits>::pos_type
135
parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
136
0
{
137
0
   if(which & ::std::ios_base::out)
138
0
      return pos_type(off_type(-1));
139
0
   off_type size = static_cast<off_type>(this->egptr() - this->eback());
140
0
   charT* g = this->eback();
141
0
   if(off_type(sp) <= size)
142
0
   {
143
0
      this->setg(g, g + off_type(sp), g + size);
144
0
   }
145
0
   return pos_type(off_type(-1));
146
0
}
147
148
//
149
// class cpp_regex_traits_base:
150
// acts as a container for locale and the facets we are using.
151
//
152
template <class charT>
153
struct cpp_regex_traits_base
154
{
155
   cpp_regex_traits_base(const std::locale& l)
156
5
   { (void)imbue(l); }
157
   std::locale imbue(const std::locale& l);
158
159
   std::locale m_locale;
160
   std::ctype<charT> const* m_pctype;
161
   std::messages<charT> const* m_pmessages;
162
   std::collate<charT> const* m_pcollate;
163
164
   bool operator<(const cpp_regex_traits_base& b)const
165
16
   {
166
16
      if(m_pctype == b.m_pctype)
167
16
      {
168
16
         if(m_pmessages == b.m_pmessages)
169
16
         {
170
16
            return m_pcollate < b.m_pcollate;
171
16
         }
172
0
         return m_pmessages < b.m_pmessages;
173
16
      }
174
0
      return m_pctype < b.m_pctype;
175
16
   }
176
   bool operator==(const cpp_regex_traits_base& b)const
177
1
   {
178
1
      return (m_pctype == b.m_pctype) 
179
1
         && (m_pmessages == b.m_pmessages) 
180
1
         && (m_pcollate == b.m_pcollate);
181
1
   }
182
};
183
184
template <class charT>
185
std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
186
5
{
187
5
   std::locale result(m_locale);
188
5
   m_locale = l;
189
5
   m_pctype = &std::use_facet<std::ctype<charT>>(l);
190
5
   m_pmessages = std::has_facet<std::messages<charT> >(l) ? &std::use_facet<std::messages<charT> >(l) : 0;
191
5
   m_pcollate = &std::use_facet<std::collate<charT> >(l);
192
5
   return result;
193
5
}
194
195
//
196
// class cpp_regex_traits_char_layer:
197
// implements methods that require specialization for narrow characters:
198
//
199
template <class charT>
200
class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
201
{
202
   typedef std::basic_string<charT> string_type;
203
   typedef std::map<charT, regex_constants::syntax_type> map_type;
204
   typedef typename map_type::const_iterator map_iterator_type;
205
public:
206
   cpp_regex_traits_char_layer(const std::locale& l)
207
      : cpp_regex_traits_base<charT>(l)
208
   {
209
      init();
210
   }
211
   cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)
212
      : cpp_regex_traits_base<charT>(b)
213
   {
214
      init();
215
   }
216
   void init();
217
218
   regex_constants::syntax_type syntax_type(charT c)const
219
   {
220
      map_iterator_type i = m_char_map.find(c);
221
      return ((i == m_char_map.end()) ? 0 : i->second);
222
   }
223
   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
224
   {
225
      map_iterator_type i = m_char_map.find(c);
226
      if(i == m_char_map.end())
227
      {
228
         if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;
229
         if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;
230
         return 0;
231
      }
232
      return i->second;
233
   }
234
235
private:
236
   string_type get_default_message(regex_constants::syntax_type);
237
   // TODO: use a hash table when available!
238
   map_type m_char_map;
239
};
240
241
template <class charT>
242
void cpp_regex_traits_char_layer<charT>::init()
243
{
244
   // we need to start by initialising our syntax map so we know which
245
   // character is used for which purpose:
246
#ifndef __IBMCPP__
247
   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
248
#else
249
   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
250
#endif
251
   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
252
   if((!cat_name.empty()) && (this->m_pmessages != 0))
253
   {
254
      cat = this->m_pmessages->open(
255
         cat_name, 
256
         this->m_locale);
257
      if((int)cat < 0)
258
      {
259
         std::string m("Unable to open message catalog: ");
260
         std::runtime_error err(m + cat_name);
261
         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
262
      }
263
   }
264
   //
265
   // if we have a valid catalog then load our messages:
266
   //
267
   if((int)cat >= 0)
268
   {
269
#ifndef BOOST_NO_EXCEPTIONS
270
      try{
271
#endif
272
         for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
273
         {
274
            string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));
275
            for(typename string_type::size_type j = 0; j < mss.size(); ++j)
276
            {
277
               m_char_map[mss[j]] = i;
278
            }
279
         }
280
         this->m_pmessages->close(cat);
281
#ifndef BOOST_NO_EXCEPTIONS
282
      }
283
      catch(...)
284
      {
285
         if(this->m_pmessages)
286
            this->m_pmessages->close(cat);
287
         throw;
288
      }
289
#endif
290
   }
291
   else
292
   {
293
      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
294
      {
295
         const char* ptr = get_default_syntax(i);
296
         while(ptr && *ptr)
297
         {
298
            m_char_map[this->m_pctype->widen(*ptr)] = i;
299
            ++ptr;
300
         }
301
      }
302
   }
303
}
304
305
template <class charT>
306
typename cpp_regex_traits_char_layer<charT>::string_type 
307
   cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
308
{
309
   const char* ptr = get_default_syntax(i);
310
   string_type result;
311
   while(ptr && *ptr)
312
   {
313
      result.append(1, this->m_pctype->widen(*ptr));
314
      ++ptr;
315
   }
316
   return result;
317
}
318
319
//
320
// specialized version for narrow characters:
321
//
322
template <>
323
class cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>
324
{
325
   typedef std::string string_type;
326
public:
327
   cpp_regex_traits_char_layer(const std::locale& l)
328
   : cpp_regex_traits_base<char>(l)
329
0
   {
330
0
      init();
331
0
   }
332
   cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
333
   : cpp_regex_traits_base<char>(l)
334
1
   {
335
1
      init();
336
1
   }
337
338
   regex_constants::syntax_type syntax_type(char c)const
339
120
   {
340
120
      return m_char_map[static_cast<unsigned char>(c)];
341
120
   }
342
   regex_constants::escape_syntax_type escape_syntax_type(char c) const
343
10
   {
344
10
      return m_char_map[static_cast<unsigned char>(c)];
345
10
   }
346
347
private:
348
   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
349
   void init();
350
};
351
352
//
353
// class cpp_regex_traits_implementation:
354
// provides pimpl implementation for cpp_regex_traits.
355
//
356
template <class charT>
357
class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
358
{
359
public:
360
   typedef typename cpp_regex_traits<charT>::char_class_type      char_class_type;
361
   typedef typename std::ctype<charT>::mask                       native_mask_type;
362
   typedef typename std::make_unsigned<native_mask_type>::type    unsigned_native_mask_type;
363
   static const char_class_type mask_blank = 1u << 24;
364
   static const char_class_type mask_word = 1u << 25;
365
   static const char_class_type mask_unicode = 1u << 26;
366
   static const char_class_type mask_horizontal = 1u << 27;
367
   static const char_class_type mask_vertical = 1u << 28;
368
369
   typedef std::basic_string<charT> string_type;
370
   typedef charT char_type;
371
   //cpp_regex_traits_implementation();
372
   cpp_regex_traits_implementation(const std::locale& l)
373
      : cpp_regex_traits_char_layer<charT>(l)
374
   {
375
      init();
376
   }
377
   cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
378
      : cpp_regex_traits_char_layer<charT>(l)
379
1
   {
380
1
      init();
381
1
   }
382
   std::string error_string(regex_constants::error_type n) const
383
0
   {
384
0
      if(!m_error_strings.empty())
385
0
      {
386
0
         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
387
0
         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
388
0
      }
389
0
      return get_default_error_string(n);
390
0
   }
391
   char_class_type lookup_classname(const charT* p1, const charT* p2) const
392
25
   {
393
25
      char_class_type result = lookup_classname_imp(p1, p2);
394
25
      if(result == 0)
395
0
      {
396
0
         string_type temp(p1, p2);
397
0
         this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());
398
0
         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
399
0
      }
400
25
      return result;
401
25
   }
402
   string_type lookup_collatename(const charT* p1, const charT* p2) const;
403
   string_type transform_primary(const charT* p1, const charT* p2) const;
404
   string_type transform(const charT* p1, const charT* p2) const;
405
private:
406
   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID
407
   std::map<string_type, char_class_type>  m_custom_class_names; // character class names
408
   std::map<string_type, string_type>      m_custom_collate_names; // collating element names
409
   unsigned                       m_collate_type;    // the form of the collation string
410
   charT                          m_collate_delim;   // the collation group delimiter
411
   //
412
   // helpers:
413
   //
414
   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
415
   void init();
416
};
417
418
template <class charT>
419
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
420
template <class charT>
421
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
422
template <class charT>
423
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;
424
template <class charT>
425
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;
426
template <class charT>
427
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;
428
429
template <class charT>
430
typename cpp_regex_traits_implementation<charT>::string_type 
431
   cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
432
0
{
433
   //
434
   // PRECONDITIONS:
435
   //
436
   // A bug in gcc 3.2 (and maybe other versions as well) treats
437
   // p1 as a null terminated string, for efficiency reasons 
438
   // we work around this elsewhere, but just assert here that
439
   // we adhere to gcc's (buggy) preconditions...
440
   //
441
0
   BOOST_REGEX_ASSERT(*p2 == 0);
442
0
   string_type result;
443
#if defined(_CPPLIB_VER)
444
   //
445
   // A bug in VC11 and 12 causes the program to hang if we pass a null-string
446
   // to std::collate::transform, but only for certain locales :-(
447
   // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
448
   //
449
   if(*p1 == 0)
450
   {
451
      return string_type(1, charT(0));
452
   }
453
#endif
454
   //
455
   // swallowing all exceptions here is a bad idea
456
   // however at least one std lib will always throw
457
   // std::bad_alloc for certain arguments...
458
   //
459
0
#ifndef BOOST_NO_EXCEPTIONS
460
0
   try{
461
0
#endif
462
      //
463
      // What we do here depends upon the format of the sort key returned by
464
      // sort key returned by this->transform:
465
      //
466
0
      switch(m_collate_type)
467
0
      {
468
0
      case sort_C:
469
0
      case sort_unknown:
470
         // the best we can do is translate to lower case, then get a regular sort key:
471
0
         {
472
0
            result.assign(p1, p2);
473
0
            this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());
474
0
            result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());
475
0
            break;
476
0
         }
477
0
      case sort_fixed:
478
0
         {
479
            // get a regular sort key, and then truncate it:
480
0
            result.assign(this->m_pcollate->transform(p1, p2));
481
0
            result.erase(this->m_collate_delim);
482
0
            break;
483
0
         }
484
0
      case sort_delim:
485
            // get a regular sort key, and then truncate everything after the delim:
486
0
            result.assign(this->m_pcollate->transform(p1, p2));
487
0
            std::size_t i;
488
0
            for(i = 0; i < result.size(); ++i)
489
0
            {
490
0
               if(result[i] == m_collate_delim)
491
0
                  break;
492
0
            }
493
0
            result.erase(i);
494
0
            break;
495
0
      }
496
0
#ifndef BOOST_NO_EXCEPTIONS
497
0
   }catch(...){}
498
0
#endif
499
0
   while((!result.empty()) && (charT(0) == *result.rbegin()))
500
0
      result.erase(result.size() - 1);
501
0
   if(result.empty())
502
0
   {
503
      // character is ignorable at the primary level:
504
0
      result = string_type(1, charT(0));
505
0
   }
506
0
   return result;
507
0
}
508
509
template <class charT>
510
typename cpp_regex_traits_implementation<charT>::string_type 
511
   cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const
512
3
{
513
   //
514
   // PRECONDITIONS:
515
   //
516
   // A bug in gcc 3.2 (and maybe other versions as well) treats
517
   // p1 as a null terminated string, for efficiency reasons 
518
   // we work around this elsewhere, but just assert here that
519
   // we adhere to gcc's (buggy) preconditions...
520
   //
521
3
   BOOST_REGEX_ASSERT(*p2 == 0);
522
   //
523
   // swallowing all exceptions here is a bad idea
524
   // however at least one std lib will always throw
525
   // std::bad_alloc for certain arguments...
526
   //
527
0
   string_type result, result2;
528
#if defined(_CPPLIB_VER)
529
   //
530
   // A bug in VC11 and 12 causes the program to hang if we pass a null-string
531
   // to std::collate::transform, but only for certain locales :-(
532
   // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
533
   //
534
   if(*p1 == 0)
535
   {
536
      return result;
537
   }
538
#endif
539
3
#ifndef BOOST_NO_EXCEPTIONS
540
3
   try{
541
3
#endif
542
3
      result = this->m_pcollate->transform(p1, p2);
543
      //
544
      // some implementations (Dinkumware) append unnecessary trailing \0's:
545
3
      while((!result.empty()) && (charT(0) == *result.rbegin()))
546
0
         result.erase(result.size() - 1);
547
      //
548
      // We may have NULL's used as separators between sections of the collate string,
549
      // an example would be Boost.Locale.  We have no way to detect this case via
550
      // #defines since this can be used with any compiler/platform combination.
551
      // Unfortunately our state machine (which was devised when all implementations
552
      // used underlying C language API's) can't cope with that case.  One workaround
553
      // is to replace each character with 2, fortunately this code isn't used that
554
      // much as this is now slower than before :-(
555
      //
556
3
      typedef typename std::make_unsigned<charT>::type uchar_type;
557
3
      result2.reserve(result.size() * 2 + 2);
558
6
      for(unsigned i = 0; i < result.size(); ++i)
559
3
      {
560
3
         if(static_cast<uchar_type>(result[i]) == (std::numeric_limits<uchar_type>::max)())
561
0
         {
562
0
            result2.append(1, charT((std::numeric_limits<uchar_type>::max)())).append(1, charT('b'));
563
0
         }
564
3
         else
565
3
         {
566
3
            result2.append(1, static_cast<charT>(1 + static_cast<uchar_type>(result[i]))).append(1, charT('b') - 1);
567
3
         }
568
3
      }
569
3
      BOOST_REGEX_ASSERT(std::find(result2.begin(), result2.end(), charT(0)) == result2.end());
570
3
#ifndef BOOST_NO_EXCEPTIONS
571
3
   }
572
3
   catch(...)
573
3
   {
574
0
   }
575
0
#endif
576
3
   return result2;
577
3
}
578
579
580
template <class charT>
581
typename cpp_regex_traits_implementation<charT>::string_type 
582
   cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
583
0
{
584
0
   typedef typename std::map<string_type, string_type>::const_iterator iter_type;
585
0
   if(!m_custom_collate_names.empty())
586
0
   {
587
0
      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
588
0
      if(pos != m_custom_collate_names.end())
589
0
         return pos->second;
590
0
   }
591
0
   std::string name(p1, p2);
592
0
   name = lookup_default_collate_name(name);
593
0
   if(!name.empty())
594
0
      return string_type(name.begin(), name.end());
595
0
   if(p2 - p1 == 1)
596
0
      return string_type(1, *p1);
597
0
   return string_type();
598
0
}
599
600
template <class charT>
601
void cpp_regex_traits_implementation<charT>::init()
602
1
{
603
1
#ifndef __IBMCPP__
604
1
   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
605
#else
606
   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
607
#endif
608
1
   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
609
1
   if((!cat_name.empty()) && (this->m_pmessages != 0))
610
0
   {
611
0
      cat = this->m_pmessages->open(
612
0
         cat_name, 
613
0
         this->m_locale);
614
0
      if((int)cat < 0)
615
0
      {
616
0
         std::string m("Unable to open message catalog: ");
617
0
         std::runtime_error err(m + cat_name);
618
0
         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
619
0
      }
620
0
   }
621
   //
622
   // if we have a valid catalog then load our messages:
623
   //
624
1
   if((int)cat >= 0)
625
0
   {
626
      //
627
      // Error messages:
628
      //
629
0
      for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0); 
630
0
         i <= boost::regex_constants::error_unknown; 
631
0
         i = static_cast<boost::regex_constants::error_type>(i + 1))
632
0
      {
633
0
         const char* p = get_default_error_string(i);
634
0
         string_type default_message;
635
0
         while(*p)
636
0
         {
637
0
            default_message.append(1, this->m_pctype->widen(*p));
638
0
            ++p;
639
0
         }
640
0
         string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);
641
0
         std::string result;
642
0
         for(std::string::size_type j = 0; j < s.size(); ++j)
643
0
         {
644
0
            result.append(1, this->m_pctype->narrow(s[j], 0));
645
0
         }
646
0
         m_error_strings[i] = result;
647
0
      }
648
      //
649
      // Custom class names:
650
      //
651
0
      static const char_class_type masks[16] = 
652
0
      {
653
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::alnum),
654
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::alpha),
655
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::cntrl),
656
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::digit),
657
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::graph),
658
0
         cpp_regex_traits_implementation<charT>::mask_horizontal,
659
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::lower),
660
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::print),
661
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::punct),
662
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::space),
663
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::upper),
664
0
         cpp_regex_traits_implementation<charT>::mask_vertical,
665
0
         static_cast<unsigned_native_mask_type>(std::ctype<charT>::xdigit),
666
0
         cpp_regex_traits_implementation<charT>::mask_blank,
667
0
         cpp_regex_traits_implementation<charT>::mask_word,
668
0
         cpp_regex_traits_implementation<charT>::mask_unicode,
669
0
      };
670
0
      static const string_type null_string;
671
0
      for(unsigned int j = 0; j <= 13; ++j)
672
0
      {
673
0
         string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));
674
0
         if(!s.empty())
675
0
            this->m_custom_class_names[s] = masks[j];
676
0
      }
677
0
   }
678
   //
679
   // get the collation format used by m_pcollate:
680
   //
681
1
   m_collate_type = BOOST_REGEX_DETAIL_NS::find_sort_syntax(this, &m_collate_delim);
682
1
}
683
684
template <class charT>
685
typename cpp_regex_traits_implementation<charT>::char_class_type 
686
   cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
687
25
{
688
25
   static const char_class_type masks[22] = 
689
25
   {
690
25
      0,
691
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum),
692
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::alpha),
693
25
      cpp_regex_traits_implementation<charT>::mask_blank,
694
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::cntrl),
695
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::digit),
696
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::digit),
697
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::graph),
698
25
      cpp_regex_traits_implementation<charT>::mask_horizontal,
699
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::lower),
700
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::lower),
701
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::print),
702
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::punct),
703
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::space),
704
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::space),
705
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::upper),
706
25
      cpp_regex_traits_implementation<charT>::mask_unicode,
707
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::upper),
708
25
      cpp_regex_traits_implementation<charT>::mask_vertical,
709
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum) | cpp_regex_traits_implementation<charT>::mask_word, 
710
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum) | cpp_regex_traits_implementation<charT>::mask_word, 
711
25
      static_cast<unsigned_native_mask_type>(std::ctype<char>::xdigit),
712
25
   };
713
25
   if(!m_custom_class_names.empty())
714
0
   {
715
0
      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
716
0
      map_iter pos = m_custom_class_names.find(string_type(p1, p2));
717
0
      if(pos != m_custom_class_names.end())
718
0
         return pos->second;
719
0
   }
720
25
   std::size_t state_id = 1 + BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);
721
25
   BOOST_REGEX_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));
722
0
   return masks[state_id];
723
25
}
724
725
template <class charT>
726
inline std::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l)
727
5
{
728
5
   cpp_regex_traits_base<charT> key(l);
729
5
   return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);
730
5
}
731
732
} // BOOST_REGEX_DETAIL_NS
733
734
template <class charT>
735
class cpp_regex_traits
736
{
737
private:
738
   typedef std::ctype<charT>            ctype_type;
739
public:
740
   typedef charT                        char_type;
741
   typedef std::size_t                  size_type;
742
   typedef std::basic_string<char_type> string_type;
743
   typedef std::locale                  locale_type;
744
   typedef std::uint_least32_t          char_class_type;
745
746
   struct boost_extensions_tag{};
747
748
   cpp_regex_traits()
749
      : m_pimpl(BOOST_REGEX_DETAIL_NS::create_cpp_regex_traits<charT>(std::locale()))
750
5
   { }
751
   static size_type length(const char_type* p)
752
5
   {
753
5
      return std::char_traits<charT>::length(p);
754
5
   }
755
   regex_constants::syntax_type syntax_type(charT c)const
756
120
   {
757
120
      return m_pimpl->syntax_type(c);
758
120
   }
759
   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
760
10
   {
761
10
      return m_pimpl->escape_syntax_type(c);
762
10
   }
763
   charT translate(charT c) const
764
   {
765
      return c;
766
   }
767
   charT translate_nocase(charT c) const
768
   {
769
      return m_pimpl->m_pctype->tolower(c);
770
   }
771
   charT translate(charT c, bool icase) const
772
5.20k
   {
773
5.20k
      return icase ? m_pimpl->m_pctype->tolower(c) : c;
774
5.20k
   }
775
   charT tolower(charT c) const
776
   {
777
      return m_pimpl->m_pctype->tolower(c);
778
   }
779
   charT toupper(charT c) const
780
   {
781
      return m_pimpl->m_pctype->toupper(c);
782
   }
783
   string_type transform(const charT* p1, const charT* p2) const
784
0
   {
785
0
      return m_pimpl->transform(p1, p2);
786
0
   }
787
   string_type transform_primary(const charT* p1, const charT* p2) const
788
0
   {
789
0
      return m_pimpl->transform_primary(p1, p2);
790
0
   }
791
   char_class_type lookup_classname(const charT* p1, const charT* p2) const
792
25
   {
793
25
      return m_pimpl->lookup_classname(p1, p2);
794
25
   }
795
   string_type lookup_collatename(const charT* p1, const charT* p2) const
796
0
   {
797
0
      return m_pimpl->lookup_collatename(p1, p2);
798
0
   }
799
   bool isctype(charT c, char_class_type f) const
800
0
   {
801
0
      typedef typename std::ctype<charT>::mask ctype_mask;
802
803
0
      static const ctype_mask mask_base = 
804
0
         static_cast<ctype_mask>(
805
0
            std::ctype<charT>::alnum 
806
0
            | std::ctype<charT>::alpha
807
0
            | std::ctype<charT>::cntrl
808
0
            | std::ctype<charT>::digit
809
0
            | std::ctype<charT>::graph
810
0
            | std::ctype<charT>::lower
811
0
            | std::ctype<charT>::print
812
0
            | std::ctype<charT>::punct
813
0
            | std::ctype<charT>::space
814
0
            | std::ctype<charT>::upper
815
0
            | std::ctype<charT>::xdigit);
816
817
0
      if((f & mask_base) 
818
0
         && (m_pimpl->m_pctype->is(
819
0
            static_cast<ctype_mask>(f & mask_base), c)))
820
0
         return true;
821
0
      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_unicode) && BOOST_REGEX_DETAIL_NS::is_extended(c))
822
0
         return true;
823
0
      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))
824
0
         return true;
825
0
      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_blank) 
826
0
         && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)
827
0
         && !BOOST_REGEX_DETAIL_NS::is_separator(c))
828
0
         return true;
829
0
      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_vertical) 
830
0
         && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\v')))
831
0
         return true;
832
0
      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_horizontal) 
833
0
         && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_vertical))
834
0
         return true;
835
#ifdef __CYGWIN__
836
      //
837
      // Cygwin has a buggy ctype facet, see https://www.cygwin.com/ml/cygwin/2012-08/msg00178.html:
838
      //
839
      else if((f & std::ctype<charT>::xdigit) == std::ctype<charT>::xdigit)
840
      {
841
         if((c >= 'a') && (c <= 'f'))
842
            return true;
843
         if((c >= 'A') && (c <= 'F'))
844
            return true;
845
      }
846
#endif
847
0
      return false;
848
0
   }
849
   std::intmax_t toi(const charT*& p1, const charT* p2, int radix)const;
850
   int value(charT c, int radix)const
851
   {
852
      const charT* pc = &c;
853
      return (int)toi(pc, pc + 1, radix);
854
   }
855
   locale_type imbue(locale_type l)
856
   {
857
      std::locale result(getloc());
858
      m_pimpl = BOOST_REGEX_DETAIL_NS::create_cpp_regex_traits<charT>(l);
859
      return result;
860
   }
861
   locale_type getloc()const
862
   {
863
      return m_pimpl->m_locale;
864
   }
865
   std::string error_string(regex_constants::error_type n) const
866
0
   {
867
0
      return m_pimpl->error_string(n);
868
0
   }
869
870
   //
871
   // extension:
872
   // set the name of the message catalog in use (defaults to "boost_regex").
873
   //
874
   static std::string catalog_name(const std::string& name);
875
   static std::string get_catalog_name();
876
877
private:
878
   std::shared_ptr<const BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT> > m_pimpl;
879
   //
880
   // catalog name handler:
881
   //
882
   static std::string& get_catalog_name_inst();
883
884
#ifdef BOOST_HAS_THREADS
885
   static std::mutex& get_mutex_inst();
886
#endif
887
};
888
889
890
template <class charT>
891
std::intmax_t cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const
892
0
{
893
0
   BOOST_REGEX_DETAIL_NS::parser_buf<charT>   sbuf;            // buffer for parsing numbers.
894
0
   std::basic_istream<charT>      is(&sbuf);       // stream for parsing numbers.
895
896
   // we do NOT want to parse any thousands separators inside the stream:
897
0
   last = std::find(first, last, std::use_facet<std::numpunct<charT>>(is.getloc()).thousands_sep());
898
899
0
   sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));
900
0
   is.clear();
901
0
   if(std::abs(radix) == 16) is >> std::hex;
902
0
   else if(std::abs(radix) == 8) is >> std::oct;
903
0
   else is >> std::dec;
904
0
   std::intmax_t val;
905
0
   if(is >> val)
906
0
   {
907
0
      first = first + ((last - first) - sbuf.in_avail());
908
0
      return val;
909
0
   }
910
0
   else
911
0
      return -1;
912
0
}
913
914
template <class charT>
915
std::string cpp_regex_traits<charT>::catalog_name(const std::string& name)
916
{
917
#ifdef BOOST_HAS_THREADS
918
   std::lock_guard<std::mutex> lk(get_mutex_inst());
919
#endif
920
   std::string result(get_catalog_name_inst());
921
   get_catalog_name_inst() = name;
922
   return result;
923
}
924
925
template <class charT>
926
std::string& cpp_regex_traits<charT>::get_catalog_name_inst()
927
2
{
928
2
   static std::string s_name;
929
2
   return s_name;
930
2
}
931
932
template <class charT>
933
std::string cpp_regex_traits<charT>::get_catalog_name()
934
2
{
935
2
#ifdef BOOST_HAS_THREADS
936
2
   std::lock_guard<std::mutex> lk(get_mutex_inst());
937
2
#endif
938
2
   std::string result(get_catalog_name_inst());
939
2
   return result;
940
2
}
941
942
#ifdef BOOST_HAS_THREADS
943
template <class charT>
944
std::mutex& cpp_regex_traits<charT>::get_mutex_inst()
945
2
{
946
2
   static std::mutex s_mutex;
947
2
   return s_mutex;
948
2
}
949
#endif
950
951
namespace BOOST_REGEX_DETAIL_NS {
952
953
   inline void cpp_regex_traits_char_layer<char>::init()
954
1
   {
955
      // we need to start by initialising our syntax map so we know which
956
      // character is used for which purpose:
957
1
      std::memset(m_char_map, 0, sizeof(m_char_map));
958
1
#ifndef __IBMCPP__
959
1
      std::messages<char>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
960
#else
961
      std::messages<char>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
962
#endif
963
1
      std::string cat_name(cpp_regex_traits<char>::get_catalog_name());
964
1
      if ((!cat_name.empty()) && (m_pmessages != 0))
965
0
      {
966
0
         cat = this->m_pmessages->open(
967
0
            cat_name,
968
0
            this->m_locale);
969
0
         if ((int)cat < 0)
970
0
         {
971
0
            std::string m("Unable to open message catalog: ");
972
0
            std::runtime_error err(m + cat_name);
973
0
            boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
974
0
         }
975
0
      }
976
      //
977
      // if we have a valid catalog then load our messages:
978
      //
979
1
      if ((int)cat >= 0)
980
0
      {
981
0
#ifndef BOOST_NO_EXCEPTIONS
982
0
         try {
983
0
#endif
984
0
            for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
985
0
            {
986
0
               string_type mss = this->m_pmessages->get(cat, 0, i, get_default_syntax(i));
987
0
               for (string_type::size_type j = 0; j < mss.size(); ++j)
988
0
               {
989
0
                  m_char_map[static_cast<unsigned char>(mss[j])] = i;
990
0
               }
991
0
            }
992
0
            this->m_pmessages->close(cat);
993
0
#ifndef BOOST_NO_EXCEPTIONS
994
0
         }
995
0
         catch (...)
996
0
         {
997
0
            this->m_pmessages->close(cat);
998
0
            throw;
999
0
         }
1000
0
#endif
1001
0
      }
1002
1
      else
1003
1
      {
1004
60
         for (regex_constants::syntax_type j = 1; j < regex_constants::syntax_max; ++j)
1005
59
         {
1006
59
            const char* ptr = get_default_syntax(j);
1007
120
            while (ptr && *ptr)
1008
61
            {
1009
61
               m_char_map[static_cast<unsigned char>(*ptr)] = j;
1010
61
               ++ptr;
1011
61
            }
1012
59
         }
1013
1
      }
1014
      //
1015
      // finish off by calculating our escape types:
1016
      //
1017
1
      unsigned char i = 'A';
1018
1
      do
1019
191
      {
1020
191
         if (m_char_map[i] == 0)
1021
157
         {
1022
157
            if (this->m_pctype->is(std::ctype_base::lower, i))
1023
12
               m_char_map[i] = regex_constants::escape_type_class;
1024
145
            else if (this->m_pctype->is(std::ctype_base::upper, i))
1025
14
               m_char_map[i] = regex_constants::escape_type_not_class;
1026
157
         }
1027
191
      } while (0xFF != i++);
1028
1
   }
1029
1030
} // namespace detail
1031
1032
1033
} // boost
1034
1035
#ifdef BOOST_REGEX_MSVC
1036
#pragma warning(pop)
1037
#endif
1038
1039
1040
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/indexed_bit_flag.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2020
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         basic_regex_parser.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares template class basic_regex_parser.
17
  */
18
19
#include <boost/regex/config.hpp>
20
#include <set>
21
22
#ifndef BOOST_REGEX_V5_INDEXED_BIT_FLAG_HPP
23
#define BOOST_REGEX_V5_INDEXED_BIT_FLAG_HPP
24
25
namespace boost{
26
namespace BOOST_REGEX_DETAIL_NS{
27
28
class indexed_bit_flag
29
{
30
   std::uint64_t low_mask;
31
   std::set<std::size_t> mask_set;
32
public:
33
5
   indexed_bit_flag() : low_mask(0) {}
34
   void set(std::size_t i)
35
5
   {
36
5
      if (i < std::numeric_limits<std::uint64_t>::digits - 1)
37
5
         low_mask |= static_cast<std::uint64_t>(1u) << i;
38
0
      else
39
0
         mask_set.insert(i);
40
5
   }
41
   bool test(std::size_t i)
42
0
   {
43
0
      if (i < std::numeric_limits<std::uint64_t>::digits - 1)
44
0
         return low_mask & static_cast<std::uint64_t>(1u) << i ? true : false;
45
0
      else
46
0
         return mask_set.find(i) != mask_set.end();
47
0
   }
48
};
49
50
} // namespace BOOST_REGEX_DETAIL_NS
51
} // namespace boost
52
53
54
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/match_flags.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 1998-2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
 
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         match_flags.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares match_flags type.
17
  */
18
19
#ifndef BOOST_REGEX_V5_MATCH_FLAGS
20
#define BOOST_REGEX_V5_MATCH_FLAGS
21
22
#ifdef __cplusplus
23
#  include <cstdint>
24
#endif
25
26
#ifdef __cplusplus
27
namespace boost{
28
   namespace regex_constants{
29
#endif
30
31
#ifdef BOOST_REGEX_MSVC
32
#pragma warning(push)
33
#if BOOST_REGEX_MSVC >= 1800
34
#pragma warning(disable : 26812)
35
#endif
36
#endif
37
38
typedef enum _match_flags
39
{
40
   match_default = 0,
41
   match_not_bol = 1,                                /* first is not start of line */
42
   match_not_eol = match_not_bol << 1,               /* last is not end of line */
43
   match_not_bob = match_not_eol << 1,               /* first is not start of buffer */
44
   match_not_eob = match_not_bob << 1,               /* last is not end of buffer */
45
   match_not_bow = match_not_eob << 1,               /* first is not start of word */
46
   match_not_eow = match_not_bow << 1,               /* last is not end of word */
47
   match_not_dot_newline = match_not_eow << 1,       /* \n is not matched by '.' */
48
   match_not_dot_null = match_not_dot_newline << 1,  /* '\0' is not matched by '.' */
49
   match_prev_avail = match_not_dot_null << 1,       /* *--first is a valid expression */
50
   match_init = match_prev_avail << 1,               /* internal use */
51
   match_any = match_init << 1,                      /* don't care what we match */
52
   match_not_null = match_any << 1,                  /* string can't be null */
53
   match_continuous = match_not_null << 1,           /* each grep match must continue from */
54
                                                     /* uninterrupted from the previous one */
55
   match_partial = match_continuous << 1,            /* find partial matches */
56
   
57
   match_stop = match_partial << 1,                  /* stop after first match (grep) V3 only */
58
   match_not_initial_null = match_stop,              /* don't match initial null, V4 only */
59
   match_all = match_stop << 1,                      /* must find the whole of input even if match_any is set */
60
   match_perl = match_all << 1,                      /* Use perl matching rules */
61
   match_posix = match_perl << 1,                    /* Use POSIX matching rules */
62
   match_nosubs = match_posix << 1,                  /* don't trap marked subs */
63
   match_extra = match_nosubs << 1,                  /* include full capture information for repeated captures */
64
   match_single_line = match_extra << 1,             /* treat text as single line and ignore any \n's when matching ^ and $. */
65
   match_unused1 = match_single_line << 1,           /* unused */
66
   match_unused2 = match_unused1 << 1,               /* unused */
67
   match_unused3 = match_unused2 << 1,               /* unused */
68
   match_max = match_unused3,
69
70
   format_perl = 0,                                  /* perl style replacement */
71
   format_default = 0,                               /* ditto. */
72
   format_sed = match_max << 1,                      /* sed style replacement. */
73
   format_all = format_sed << 1,                     /* enable all extensions to syntax. */
74
   format_no_copy = format_all << 1,                 /* don't copy non-matching segments. */
75
   format_first_only = format_no_copy << 1,          /* Only replace first occurrence. */
76
   format_is_if = format_first_only << 1,            /* internal use only. */
77
   format_literal = format_is_if << 1,               /* treat string as a literal */
78
79
   match_not_any = match_not_bol | match_not_eol | match_not_bob 
80
      | match_not_eob | match_not_bow | match_not_eow | match_not_dot_newline 
81
      | match_not_dot_null | match_prev_avail | match_init | match_not_null
82
      | match_continuous | match_partial | match_stop | match_not_initial_null 
83
      | match_stop | match_all | match_perl | match_posix | match_nosubs
84
      | match_extra | match_single_line | match_unused1 | match_unused2 
85
      | match_unused3 | match_max | format_perl | format_default | format_sed
86
      | format_all | format_no_copy | format_first_only | format_is_if
87
      | format_literal
88
89
90
} match_flags;
91
92
typedef match_flags match_flag_type;
93
94
#ifdef __cplusplus
95
inline match_flags operator&(match_flags m1, match_flags m2)
96
131
{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) & static_cast<std::int32_t>(m2)); }
97
inline match_flags operator|(match_flags m1, match_flags m2)
98
20
{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) | static_cast<std::int32_t>(m2)); }
99
inline match_flags operator^(match_flags m1, match_flags m2)
100
0
{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) ^ static_cast<std::int32_t>(m2)); }
101
inline match_flags operator~(match_flags m1)
102
0
{ return static_cast<match_flags>(~static_cast<std::int32_t>(m1)); }
103
inline match_flags& operator&=(match_flags& m1, match_flags m2)
104
0
{ m1 = m1&m2; return m1; }
105
inline match_flags& operator|=(match_flags& m1, match_flags m2)
106
10
{ m1 = m1|m2; return m1; }
107
inline match_flags& operator^=(match_flags& m1, match_flags m2)
108
0
{ m1 = m1^m2; return m1; }
109
#endif
110
111
#ifdef __cplusplus
112
} /* namespace regex_constants */
113
/*
114
 * import names into boost for backwards compatibility:
115
 */
116
using regex_constants::match_flag_type;
117
using regex_constants::match_default;
118
using regex_constants::match_not_bol;
119
using regex_constants::match_not_eol;
120
using regex_constants::match_not_bob;
121
using regex_constants::match_not_eob;
122
using regex_constants::match_not_bow;
123
using regex_constants::match_not_eow;
124
using regex_constants::match_not_dot_newline;
125
using regex_constants::match_not_dot_null;
126
using regex_constants::match_prev_avail;
127
/* using regex_constants::match_init; */
128
using regex_constants::match_any;
129
using regex_constants::match_not_null;
130
using regex_constants::match_continuous;
131
using regex_constants::match_partial;
132
/*using regex_constants::match_stop; */
133
using regex_constants::match_all;
134
using regex_constants::match_perl;
135
using regex_constants::match_posix;
136
using regex_constants::match_nosubs;
137
using regex_constants::match_extra;
138
using regex_constants::match_single_line;
139
/*using regex_constants::match_max; */
140
using regex_constants::format_all;
141
using regex_constants::format_sed;
142
using regex_constants::format_perl;
143
using regex_constants::format_default;
144
using regex_constants::format_no_copy;
145
using regex_constants::format_first_only;
146
/*using regex_constants::format_is_if;*/
147
148
#ifdef BOOST_REGEX_MSVC
149
#pragma warning(pop)
150
#endif
151
152
153
} /* namespace boost */
154
#endif /* __cplusplus */
155
#endif /* include guard */
156
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/match_results.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 1998-2009
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         match_results.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares template class match_results.
17
  */
18
19
#ifndef BOOST_REGEX_V5_MATCH_RESULTS_HPP
20
#define BOOST_REGEX_V5_MATCH_RESULTS_HPP
21
22
namespace boost{
23
#ifdef BOOST_REGEX_MSVC
24
#pragma warning(push)
25
#pragma warning(disable : 4251 4459)
26
#if BOOST_REGEX_MSVC < 1700
27
#     pragma warning(disable : 4231)
28
#endif
29
#  if BOOST_REGEX_MSVC < 1600
30
#     pragma warning(disable : 4660)
31
#  endif
32
#endif
33
34
namespace BOOST_REGEX_DETAIL_NS{
35
36
class named_subexpressions;
37
38
}
39
40
template <class BidiIterator, class Allocator>
41
class match_results
42
{ 
43
private:
44
   typedef          std::vector<sub_match<BidiIterator>, Allocator> vector_type;
45
public: 
46
   typedef          sub_match<BidiIterator>                         value_type;
47
   typedef typename std::allocator_traits<Allocator>::value_type const &    const_reference;
48
   typedef          const_reference                                         reference;
49
   typedef typename vector_type::const_iterator                             const_iterator;
50
   typedef          const_iterator                                          iterator;
51
   typedef typename std::iterator_traits<
52
                                    BidiIterator>::difference_type          difference_type;
53
   typedef typename std::allocator_traits<Allocator>::size_type             size_type;
54
   typedef          Allocator                                               allocator_type;
55
   typedef typename std::iterator_traits<
56
                                    BidiIterator>::value_type               char_type;
57
   typedef          std::basic_string<char_type>                            string_type;
58
   typedef          BOOST_REGEX_DETAIL_NS::named_subexpressions             named_sub_type;
59
60
   // construct/copy/destroy:
61
   explicit match_results(const Allocator& a = Allocator())
62
5
      : m_subs(a), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) {}
63
   //
64
   // IMPORTANT: in the code below, the crazy looking checks around m_is_singular are
65
   // all required because it is illegal to copy a singular iterator.
66
   // See https://svn.boost.org/trac/boost/ticket/3632.
67
   //
68
   match_results(const match_results& m)
69
      : m_subs(m.m_subs), m_base(), m_null(), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular)
70
0
   {
71
0
      if(!m_is_singular)
72
0
      {
73
0
         m_base = m.m_base;
74
0
         m_null = m.m_null;
75
0
      }
76
0
   }
77
   match_results& operator=(const match_results& m)
78
0
   {
79
0
      m_subs = m.m_subs;
80
0
      m_named_subs = m.m_named_subs;
81
0
      m_last_closed_paren = m.m_last_closed_paren;
82
0
      m_is_singular = m.m_is_singular;
83
0
      if(!m_is_singular)
84
0
      {
85
0
         m_base = m.m_base;
86
0
         m_null = m.m_null;
87
0
      }
88
0
      return *this;
89
0
   }
90
5
   ~match_results(){}
91
92
   // size:
93
   size_type size() const
94
0
   { return empty() ? 0 : m_subs.size() - 2; }
95
   size_type max_size() const
96
   { return m_subs.max_size(); }
97
   bool empty() const
98
0
   { return m_subs.size() < 2; }
99
   // element access:
100
   difference_type length(int sub = 0) const
101
   {
102
      if(m_is_singular)
103
         raise_logic_error();
104
      sub += 2;
105
      if((sub < (int)m_subs.size()) && (sub > 0))
106
         return m_subs[sub].length();
107
      return 0;
108
   }
109
   difference_type length(const char_type* sub) const
110
   {
111
      if(m_is_singular)
112
         raise_logic_error();
113
      const char_type* sub_end = sub;
114
      while(*sub_end) ++sub_end;
115
      return length(named_subexpression_index(sub, sub_end));
116
   }
117
   template <class charT>
118
   difference_type length(const charT* sub) const
119
   {
120
      if(m_is_singular)
121
         raise_logic_error();
122
      const charT* sub_end = sub;
123
      while(*sub_end) ++sub_end;
124
      return length(named_subexpression_index(sub, sub_end));
125
   }
126
   template <class charT, class Traits, class A>
127
   difference_type length(const std::basic_string<charT, Traits, A>& sub) const
128
   {
129
      return length(sub.c_str());
130
   }
131
   difference_type position(size_type sub = 0) const
132
   {
133
      if(m_is_singular)
134
         raise_logic_error();
135
      sub += 2;
136
      if(sub < m_subs.size())
137
      {
138
         const sub_match<BidiIterator>& s = m_subs[sub];
139
         if(s.matched || (sub == 2))
140
         {
141
            return std::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
142
         }
143
      }
144
      return ~static_cast<difference_type>(0);
145
   }
146
   difference_type position(const char_type* sub) const
147
   {
148
      const char_type* sub_end = sub;
149
      while(*sub_end) ++sub_end;
150
      return position(named_subexpression_index(sub, sub_end));
151
   }
152
   template <class charT>
153
   difference_type position(const charT* sub) const
154
   {
155
      const charT* sub_end = sub;
156
      while(*sub_end) ++sub_end;
157
      return position(named_subexpression_index(sub, sub_end));
158
   }
159
   template <class charT, class Traits, class A>
160
   difference_type position(const std::basic_string<charT, Traits, A>& sub) const
161
   {
162
      return position(sub.c_str());
163
   }
164
   string_type str(int sub = 0) const
165
   {
166
      if(m_is_singular)
167
         raise_logic_error();
168
      sub += 2;
169
      string_type result;
170
      if(sub < (int)m_subs.size() && (sub > 0))
171
      {
172
         const sub_match<BidiIterator>& s = m_subs[sub];
173
         if(s.matched)
174
         {
175
            result = s.str();
176
         }
177
      }
178
      return result;
179
   }
180
   string_type str(const char_type* sub) const
181
   {
182
      return (*this)[sub].str();
183
   }
184
   template <class Traits, class A>
185
   string_type str(const std::basic_string<char_type, Traits, A>& sub) const
186
   {
187
      return (*this)[sub].str();
188
   }
189
   template <class charT>
190
   string_type str(const charT* sub) const
191
   {
192
      return (*this)[sub].str();
193
   }
194
   template <class charT, class Traits, class A>
195
   string_type str(const std::basic_string<charT, Traits, A>& sub) const
196
   {
197
      return (*this)[sub].str();
198
   }
199
   const_reference operator[](int sub) const
200
21
   {
201
21
      if(m_is_singular && m_subs.empty())
202
0
         raise_logic_error();
203
21
      sub += 2;
204
21
      if(sub < (int)m_subs.size() && (sub >= 0))
205
21
      {
206
21
         return m_subs[sub];
207
21
      }
208
0
      return m_null;
209
21
   }
210
   //
211
   // Named sub-expressions:
212
   //
213
   const_reference named_subexpression(const char_type* i, const char_type* j) const
214
   {
215
      //
216
      // Scan for the leftmost *matched* subexpression with the specified named:
217
      //
218
      if(m_is_singular)
219
         raise_logic_error();
220
      BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type r = m_named_subs->equal_range(i, j);
221
      while((r.first != r.second) && ((*this)[r.first->index].matched == false))
222
         ++r.first;
223
      return r.first != r.second ? (*this)[r.first->index] : m_null;
224
   }
225
   template <class charT>
226
   const_reference named_subexpression(const charT* i, const charT* j) const
227
   {
228
      static_assert(sizeof(charT) <= sizeof(char_type), "Failed internal logic");
229
      if(i == j)
230
         return m_null;
231
      std::vector<char_type> s;
232
      while(i != j)
233
         s.insert(s.end(), *i++);
234
      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
235
   }
236
   int named_subexpression_index(const char_type* i, const char_type* j) const
237
   {
238
      //
239
      // Scan for the leftmost *matched* subexpression with the specified named.
240
      // If none found then return the leftmost expression with that name,
241
      // otherwise an invalid index:
242
      //
243
      if(m_is_singular)
244
         raise_logic_error();
245
      BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type s, r;
246
      s = r = m_named_subs->equal_range(i, j);
247
      while((r.first != r.second) && ((*this)[r.first->index].matched == false))
248
         ++r.first;
249
      if(r.first == r.second)
250
         r = s;
251
      return r.first != r.second ? r.first->index : -20;
252
   }
253
   template <class charT>
254
   int named_subexpression_index(const charT* i, const charT* j) const
255
   {
256
      static_assert(sizeof(charT) <= sizeof(char_type), "Failed internal logic");
257
      if(i == j)
258
         return -20;
259
      std::vector<char_type> s;
260
      while(i != j)
261
         s.insert(s.end(), *i++);
262
      return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());
263
   }
264
   template <class Traits, class A>
265
   const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const
266
   {
267
      return named_subexpression(s.c_str(), s.c_str() + s.size());
268
   }
269
   const_reference operator[](const char_type* p) const
270
   {
271
      const char_type* e = p;
272
      while(*e) ++e;
273
      return named_subexpression(p, e);
274
   }
275
276
   template <class charT>
277
   const_reference operator[](const charT* p) const
278
   {
279
      static_assert(sizeof(charT) <= sizeof(char_type), "Failed internal logic");
280
      if(*p == 0)
281
         return m_null;
282
      std::vector<char_type> s;
283
      while(*p)
284
         s.insert(s.end(), *p++);
285
      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
286
   }
287
   template <class charT, class Traits, class A>
288
   const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const
289
   {
290
      static_assert(sizeof(charT) <= sizeof(char_type), "Failed internal logic");
291
      if(ns.empty())
292
         return m_null;
293
      std::vector<char_type> s;
294
      for(unsigned i = 0; i < ns.size(); ++i)
295
         s.insert(s.end(), ns[i]);
296
      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
297
   }
298
299
   const_reference prefix() const
300
0
   {
301
0
      if(m_is_singular)
302
0
         raise_logic_error();
303
0
      return (*this)[-1];
304
0
   }
305
306
   const_reference suffix() const
307
0
   {
308
0
      if(m_is_singular)
309
0
         raise_logic_error();
310
0
      return (*this)[-2];
311
0
   }
312
   const_iterator begin() const
313
0
   {
314
0
      return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();
315
0
   }
316
   const_iterator end() const
317
   {
318
      return m_subs.end();
319
   }
320
   // format:
321
   template <class OutputIterator, class Functor>
322
   OutputIterator format(OutputIterator out,
323
                         Functor fmt,
324
                         match_flag_type flags = format_default) const
325
   {
326
      if(m_is_singular)
327
         raise_logic_error();
328
      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;
329
      F func(fmt);
330
      return func(*this, out, flags);
331
   }
332
   template <class Functor>
333
   string_type format(Functor fmt, match_flag_type flags = format_default) const
334
   {
335
      if(m_is_singular)
336
         raise_logic_error();
337
      std::basic_string<char_type> result;
338
      BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);
339
340
      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > >::type F;
341
      F func(fmt);
342
343
      func(*this, i, flags);
344
      return result;
345
   }
346
   // format with locale:
347
   template <class OutputIterator, class Functor, class RegexT>
348
   OutputIterator format(OutputIterator out,
349
                         Functor fmt,
350
                         match_flag_type flags,
351
                         const RegexT& re) const
352
   {
353
      if(m_is_singular)
354
         raise_logic_error();
355
      typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
356
      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;
357
      F func(fmt);
358
      return func(*this, out, flags, re.get_traits());
359
   }
360
   template <class RegexT, class Functor>
361
   string_type format(Functor fmt,
362
                      match_flag_type flags,
363
                      const RegexT& re) const
364
   {
365
      if(m_is_singular)
366
         raise_logic_error();
367
      typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
368
      std::basic_string<char_type> result;
369
      BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);
370
371
      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> >, traits_type >::type F;
372
      F func(fmt);
373
374
      func(*this, i, flags, re.get_traits());
375
      return result;
376
   }
377
378
   const_reference get_last_closed_paren()const
379
   {
380
      if(m_is_singular)
381
         raise_logic_error();
382
      return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];
383
   }
384
385
   allocator_type get_allocator() const
386
   {
387
      return m_subs.get_allocator();
388
   }
389
   void swap(match_results& that)
390
   {
391
      std::swap(m_subs, that.m_subs);
392
      std::swap(m_named_subs, that.m_named_subs);
393
      std::swap(m_last_closed_paren, that.m_last_closed_paren);
394
      if(m_is_singular)
395
      {
396
         if(!that.m_is_singular)
397
         {
398
            m_base = that.m_base;
399
            m_null = that.m_null;
400
         }
401
      }
402
      else if(that.m_is_singular)
403
      {
404
         that.m_base = m_base;
405
         that.m_null = m_null;
406
      }
407
      else
408
      {
409
         std::swap(m_base, that.m_base);
410
         std::swap(m_null, that.m_null);
411
      }
412
      std::swap(m_is_singular, that.m_is_singular);
413
   }
414
   bool operator==(const match_results& that)const
415
   {
416
      if(m_is_singular)
417
      {
418
         return that.m_is_singular;
419
      }
420
      else if(that.m_is_singular)
421
      {
422
         return false;
423
      }
424
      return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);
425
   }
426
   bool operator!=(const match_results& that)const
427
   { return !(*this == that); }
428
429
#ifdef BOOST_REGEX_MATCH_EXTRA
430
   typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;
431
432
   const capture_sequence_type& captures(int i)const
433
   {
434
      if(m_is_singular)
435
         raise_logic_error();
436
      return (*this)[i].captures();
437
   }
438
#endif
439
440
   //
441
   // private access functions:
442
   void  set_second(BidiIterator i)
443
3
   {
444
3
      BOOST_REGEX_ASSERT(m_subs.size() > 2);
445
0
      m_subs[2].second = i;
446
3
      m_subs[2].matched = true;
447
3
      m_subs[0].first = i;
448
3
      m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
449
3
      m_null.first = i;
450
3
      m_null.second = i;
451
3
      m_null.matched = false;
452
3
      m_is_singular = false;
453
3
   }
454
455
   void  set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
456
15
   {
457
15
      if(pos)
458
15
         m_last_closed_paren = static_cast<int>(pos);
459
15
      pos += 2;
460
15
      BOOST_REGEX_ASSERT(m_subs.size() > pos);
461
0
      m_subs[pos].second = i;
462
15
      m_subs[pos].matched = m;
463
15
      if((pos == 2) && !escape_k)
464
0
      {
465
0
         m_subs[0].first = i;
466
0
         m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
467
0
         m_null.first = i;
468
0
         m_null.second = i;
469
0
         m_null.matched = false;
470
0
         m_is_singular = false;
471
0
      }
472
15
   }
473
   void  set_size(size_type n, BidiIterator i, BidiIterator j)
474
5
   {
475
5
      value_type v(j);
476
5
      size_type len = m_subs.size();
477
5
      if(len > n + 2)
478
0
      {
479
0
         m_subs.erase(m_subs.begin()+n+2, m_subs.end());
480
0
         std::fill(m_subs.begin(), m_subs.end(), v);
481
0
      }
482
5
      else
483
5
      {
484
5
         std::fill(m_subs.begin(), m_subs.end(), v);
485
5
         if(n+2 != len)
486
5
            m_subs.insert(m_subs.end(), n+2-len, v);
487
5
      }
488
5
      m_subs[1].first = i;
489
5
      m_last_closed_paren = 0;
490
5
   }
491
   void  set_base(BidiIterator pos)
492
5
   {
493
5
      m_base = pos;
494
5
   }
495
   BidiIterator base()const
496
   {
497
      return m_base;
498
   }
499
   void  set_first(BidiIterator i)
500
5
   {
501
5
      BOOST_REGEX_ASSERT(m_subs.size() > 2);
502
      // set up prefix:
503
0
      m_subs[1].second = i;
504
5
      m_subs[1].matched = (m_subs[1].first != i);
505
      // set up $0:
506
5
      m_subs[2].first = i;
507
      // zero out everything else:
508
10
      for(size_type n = 3; n < m_subs.size(); ++n)
509
5
      {
510
5
         m_subs[n].first = m_subs[n].second = m_subs[0].second;
511
5
         m_subs[n].matched = false;
512
5
      }
513
5
   }
514
   void  set_first(BidiIterator i, size_type pos, bool escape_k = false)
515
15
   {
516
15
      BOOST_REGEX_ASSERT(pos+2 < m_subs.size());
517
15
      if(pos || escape_k)
518
15
      {
519
15
         m_subs[pos+2].first = i;
520
15
         if(escape_k)
521
0
         {
522
0
            m_subs[1].second = i;
523
0
            m_subs[1].matched = (m_subs[1].first != m_subs[1].second);
524
0
         }
525
15
      }
526
0
      else
527
0
         set_first(i);
528
15
   }
529
   void  maybe_assign(const match_results<BidiIterator, Allocator>& m);
530
531
   void  set_named_subs(std::shared_ptr<named_sub_type> subs)
532
5
   {
533
5
      m_named_subs = subs;
534
5
   }
535
536
private:
537
   //
538
   // Error handler called when an uninitialized match_results is accessed:
539
   //
540
   static void raise_logic_error()
541
0
   {
542
0
      std::logic_error e("Attempt to access an uninitialized boost::match_results<> class.");
543
0
#ifndef BOOST_REGEX_STANDALONE
544
0
      boost::throw_exception(e);
545
#else
546
      throw e;
547
#endif
548
0
   }
549
550
551
   vector_type            m_subs;                      // subexpressions
552
   BidiIterator   m_base;                              // where the search started from
553
   sub_match<BidiIterator> m_null;                     // a null match
554
   std::shared_ptr<named_sub_type> m_named_subs;     // Shared copy of named subs in the regex object
555
   int m_last_closed_paren;                            // Last ) to be seen - used for formatting
556
   bool m_is_singular;                                 // True if our stored iterators are singular
557
};
558
559
template <class BidiIterator, class Allocator>
560
void  match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)
561
0
{
562
0
   if(m_is_singular)
563
0
   {
564
0
      *this = m;
565
0
      return;
566
0
   }
567
0
   const_iterator p1, p2;
568
0
   p1 = begin();
569
0
   p2 = m.begin();
570
   //
571
   // Distances are measured from the start of *this* match, unless this isn't
572
   // a valid match in which case we use the start of the whole sequence.  Note that
573
   // no subsequent match-candidate can ever be to the left of the first match found.
574
   // This ensures that when we are using bidirectional iterators, that distances 
575
   // measured are as short as possible, and therefore as efficient as possible
576
   // to compute.  Finally note that we don't use the "matched" data member to test
577
   // whether a sub-expression is a valid match, because partial matches set this
578
   // to false for sub-expression 0.
579
   //
580
0
   BidiIterator l_end = this->suffix().second;
581
0
   BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;
582
0
   difference_type len1 = 0;
583
0
   difference_type len2 = 0;
584
0
   difference_type base1 = 0;
585
0
   difference_type base2 = 0;
586
0
   std::size_t i;
587
0
   for(i = 0; i < size(); ++i, ++p1, ++p2)
588
0
   {
589
      //
590
      // Leftmost takes priority over longest; handle special cases
591
      // where distances need not be computed first (an optimisation
592
      // for bidirectional iterators: ensure that we don't accidently
593
      // compute the length of the whole sequence, as this can be really
594
      // expensive).
595
      //
596
0
      if(p1->first == l_end)
597
0
      {
598
0
         if(p2->first != l_end)
599
0
         {
600
            // p2 must be better than p1, and no need to calculate
601
            // actual distances:
602
0
            base1 = 1;
603
0
            base2 = 0;
604
0
            break;
605
0
         }
606
0
         else
607
0
         {
608
            // *p1 and *p2 are either unmatched or match end-of sequence,
609
            // either way no need to calculate distances:
610
0
            if((p1->matched == false) && (p2->matched == true))
611
0
               break;
612
0
            if((p1->matched == true) && (p2->matched == false))
613
0
               return;
614
0
            continue;
615
0
         }
616
0
      }
617
0
      else if(p2->first == l_end)
618
0
      {
619
         // p1 better than p2, and no need to calculate distances:
620
0
         return;
621
0
      }
622
0
      base1 = std::distance(l_base, p1->first);
623
0
      base2 = std::distance(l_base, p2->first);
624
0
      BOOST_REGEX_ASSERT(base1 >= 0);
625
0
      BOOST_REGEX_ASSERT(base2 >= 0);
626
0
      if(base1 < base2) return;
627
0
      if(base2 < base1) break;
628
629
0
      len1 = std::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
630
0
      len2 = std::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
631
0
      BOOST_REGEX_ASSERT(len1 >= 0);
632
0
      BOOST_REGEX_ASSERT(len2 >= 0);
633
0
      if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
634
0
         break;
635
0
      if((p1->matched == true) && (p2->matched == false))
636
0
         return;
637
0
   }
638
0
   if(i == size())
639
0
      return;
640
0
   if(base2 < base1)
641
0
      *this = m;
642
0
   else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
643
0
      *this = m;
644
0
}
645
646
template <class BidiIterator, class Allocator>
647
void swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)
648
{
649
   a.swap(b);
650
}
651
652
template <class charT, class traits, class BidiIterator, class Allocator>
653
std::basic_ostream<charT, traits>&
654
   operator << (std::basic_ostream<charT, traits>& os,
655
                const match_results<BidiIterator, Allocator>& s)
656
{
657
   return (os << s.str());
658
}
659
660
#ifdef BOOST_REGEX_MSVC
661
#pragma warning(pop)
662
#endif
663
} // namespace boost
664
665
#endif
666
667
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/mem_block_cache.hpp
Line
Count
Source (jump to first uncovered line)
1
 /*
2
 * Copyright (c) 2002
3
 * John Maddock
4
 *
5
 * Use, modification and distribution are subject to the 
6
 * Boost Software License, Version 1.0. (See accompanying file 
7
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
 *
9
 */
10
11
 /*
12
  *   LOCATION:    see http://www.boost.org for most recent version.
13
  *   FILE         mem_block_cache.hpp
14
  *   VERSION      see <boost/version.hpp>
15
  *   DESCRIPTION: memory block cache used by the non-recursive matcher.
16
  */
17
18
#ifndef BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP
19
#define BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP
20
21
#include <new>
22
#ifdef BOOST_HAS_THREADS
23
#include <mutex>
24
#endif
25
26
#ifndef BOOST_NO_CXX11_HDR_ATOMIC
27
  #include <atomic>
28
  #if ATOMIC_POINTER_LOCK_FREE == 2
29
    #define BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE
30
    #define BOOST_REGEX_ATOMIC_POINTER std::atomic
31
  #endif
32
#endif
33
34
namespace boost{
35
namespace BOOST_REGEX_DETAIL_NS{
36
37
#ifdef BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE /* lock free implementation */
38
struct mem_block_cache
39
{
40
  std::atomic<void*> cache[BOOST_REGEX_MAX_CACHE_BLOCKS];
41
42
   ~mem_block_cache()
43
1
   {
44
17
     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
45
16
       if (cache[i].load()) ::operator delete(cache[i].load());
46
16
     }
47
1
   }
48
   void* get()
49
5
   {
50
21
     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
51
20
       void* p = cache[i].load();
52
20
       if (p != NULL) {
53
4
         if (cache[i].compare_exchange_strong(p, NULL)) return p;
54
4
       }
55
20
     }
56
1
     return ::operator new(BOOST_REGEX_BLOCKSIZE);
57
5
   }
58
   void put(void* ptr)
59
5
   {
60
5
     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
61
5
       void* p = cache[i].load();
62
5
       if (p == NULL) {
63
5
         if (cache[i].compare_exchange_strong(p, ptr)) return;
64
5
       }
65
5
     }
66
0
     ::operator delete(ptr);
67
0
   }
68
69
   static mem_block_cache& instance()
70
10
   {
71
10
      static mem_block_cache block_cache = { { {nullptr} } };
72
10
      return block_cache;
73
10
   }
74
};
75
76
77
#else /* lock-based implementation */
78
79
80
struct mem_block_node
81
{
82
   mem_block_node* next;
83
};
84
85
struct mem_block_cache
86
{
87
   // this member has to be statically initialsed:
88
   mem_block_node* next;
89
   unsigned cached_blocks;
90
#ifdef BOOST_HAS_THREADS
91
   boost::static_mutex mut;
92
#endif
93
94
   ~mem_block_cache()
95
   {
96
      while(next)
97
      {
98
         mem_block_node* old = next;
99
         next = next->next;
100
         ::operator delete(old);
101
      }
102
   }
103
   void* get()
104
   {
105
#ifdef BOOST_HAS_THREADS
106
      std::lock_guard<std::mutex> g(mut);
107
#endif
108
     if(next)
109
      {
110
         mem_block_node* result = next;
111
         next = next->next;
112
         --cached_blocks;
113
         return result;
114
      }
115
      return ::operator new(BOOST_REGEX_BLOCKSIZE);
116
   }
117
   void put(void* p)
118
   {
119
#ifdef BOOST_HAS_THREADS
120
      std::lock_guard<std::mutex> g(mut);
121
#endif
122
      if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)
123
      {
124
         ::operator delete(p);
125
      }
126
      else
127
      {
128
         mem_block_node* old = static_cast<mem_block_node*>(p);
129
         old->next = next;
130
         next = old;
131
         ++cached_blocks;
132
      }
133
   }
134
   static mem_block_cache& instance()
135
   {
136
#ifdef BOOST_HAS_THREADS
137
      static mem_block_cache block_cache = { 0, 0, BOOST_STATIC_MUTEX_INIT, };
138
#else
139
      static mem_block_cache block_cache = { 0, 0, };
140
#endif
141
      return block_cache;
142
   }
143
};
144
#endif
145
146
#if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
147
148
inline void*  get_mem_block()
149
{
150
   return ::operator new(BOOST_REGEX_BLOCKSIZE);
151
}
152
153
inline void  put_mem_block(void* p)
154
{
155
   ::operator delete(p);
156
}
157
158
#else
159
160
inline void*  get_mem_block()
161
5
{
162
5
   return mem_block_cache::instance().get();
163
5
}
164
165
inline void  put_mem_block(void* p)
166
5
{
167
5
   mem_block_cache::instance().put(p);
168
5
}
169
170
#endif
171
}
172
} // namespace boost
173
174
#endif
175
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/object_cache.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2004
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         object_cache.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Implements a generic object cache.
17
  */
18
19
#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
20
#define BOOST_REGEX_OBJECT_CACHE_HPP
21
22
#include <boost/regex/config.hpp>
23
#include <memory>
24
#include <map>
25
#include <list>
26
#include <stdexcept>
27
#include <string>
28
#ifdef BOOST_HAS_THREADS
29
#include <mutex>
30
#endif
31
32
namespace boost{
33
34
template <class Key, class Object>
35
class object_cache
36
{
37
public:
38
   typedef std::pair< ::std::shared_ptr<Object const>, Key const*> value_type;
39
   typedef std::list<value_type> list_type;
40
   typedef typename list_type::iterator list_iterator;
41
   typedef std::map<Key, list_iterator> map_type;
42
   typedef typename map_type::iterator map_iterator;
43
   typedef typename list_type::size_type size_type;
44
   static std::shared_ptr<Object const> get(const Key& k, size_type l_max_cache_size);
45
46
private:
47
   static std::shared_ptr<Object const> do_get(const Key& k, size_type l_max_cache_size);
48
49
   struct data
50
   {
51
      list_type   cont;
52
      map_type    index;
53
   };
54
55
   // Needed by compilers not implementing the resolution to DR45. For reference,
56
   // see http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
57
   friend struct data;
58
};
59
60
#ifdef BOOST_REGEX_MSVC
61
#pragma warning(push)
62
#pragma warning(disable: 4702)
63
#endif
64
template <class Key, class Object>
65
std::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, size_type l_max_cache_size)
66
5
{
67
5
#ifdef BOOST_HAS_THREADS
68
5
   static std::mutex mut;
69
5
   std::lock_guard<std::mutex> l(mut);
70
5
   return do_get(k, l_max_cache_size);
71
#else
72
   return do_get(k, l_max_cache_size);
73
#endif
74
5
}
75
#ifdef BOOST_REGEX_MSVC
76
#pragma warning(pop)
77
#endif
78
79
template <class Key, class Object>
80
std::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, size_type l_max_cache_size)
81
5
{
82
5
   typedef typename object_cache<Key, Object>::data object_data;
83
5
   typedef typename map_type::size_type map_size_type;
84
5
   static object_data s_data;
85
86
   //
87
   // see if the object is already in the cache:
88
   //
89
5
   map_iterator mpos = s_data.index.find(k);
90
5
   if(mpos != s_data.index.end())
91
4
   {
92
      //
93
      // Eureka! 
94
      // We have a cached item, bump it up the list and return it:
95
      //
96
4
      if(--(s_data.cont.end()) != mpos->second)
97
0
      {
98
         // splice out the item we want to move:
99
0
         list_type temp;
100
0
         temp.splice(temp.end(), s_data.cont, mpos->second);
101
         // and now place it at the end of the list:
102
0
         s_data.cont.splice(s_data.cont.end(), temp, temp.begin());
103
0
         BOOST_REGEX_ASSERT(*(s_data.cont.back().second) == k);
104
         // update index with new position:
105
0
         mpos->second = --(s_data.cont.end());
106
0
         BOOST_REGEX_ASSERT(&(mpos->first) == mpos->second->second);
107
0
         BOOST_REGEX_ASSERT(&(mpos->first) == s_data.cont.back().second);
108
0
      }
109
0
      return s_data.cont.back().first;
110
4
   }
111
   //
112
   // if we get here then the item is not in the cache,
113
   // so create it:
114
   //
115
1
   std::shared_ptr<Object const> result(new Object(k));
116
   //
117
   // Add it to the list, and index it:
118
   //
119
1
   s_data.cont.push_back(value_type(result, static_cast<Key const*>(0)));
120
1
   s_data.index.insert(std::make_pair(k, --(s_data.cont.end())));
121
1
   s_data.cont.back().second = &(s_data.index.find(k)->first);
122
1
   map_size_type s = s_data.index.size();
123
1
   BOOST_REGEX_ASSERT(s_data.index[k]->first.get() == result.get());
124
1
   BOOST_REGEX_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);
125
1
   BOOST_REGEX_ASSERT(s_data.index.find(k)->first == k);
126
1
   if(s > l_max_cache_size)
127
0
   {
128
      //
129
      // We have too many items in the list, so we need to start
130
      // popping them off the back of the list, but only if they're
131
      // being held uniquely by us:
132
      //
133
0
      list_iterator pos = s_data.cont.begin();
134
0
      list_iterator last = s_data.cont.end();
135
0
      while((pos != last) && (s > l_max_cache_size))
136
0
      {
137
0
         if(pos->first.use_count() == 1)
138
0
         {
139
0
            list_iterator condemmed(pos);
140
0
            ++pos;
141
            // now remove the items from our containers, 
142
            // then order has to be as follows:
143
0
            BOOST_REGEX_ASSERT(s_data.index.find(*(condemmed->second)) != s_data.index.end());
144
0
            s_data.index.erase(*(condemmed->second));
145
0
            s_data.cont.erase(condemmed); 
146
0
            --s;
147
0
         }
148
0
         else
149
0
            ++pos;
150
0
      }
151
0
      BOOST_REGEX_ASSERT(s_data.index[k]->first.get() == result.get());
152
0
      BOOST_REGEX_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);
153
0
      BOOST_REGEX_ASSERT(s_data.index.find(k)->first == k);
154
0
   }
155
0
   return result;
156
5
}
157
158
}
159
160
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/pattern_except.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 1998-2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
 
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         pattern_except.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares pattern-matching exception classes.
17
  */
18
19
#ifndef BOOST_RE_V5_PAT_EXCEPT_HPP
20
#define BOOST_RE_V5_PAT_EXCEPT_HPP
21
22
#ifndef BOOST_REGEX_CONFIG_HPP
23
#include <boost/regex/config.hpp>
24
#endif
25
26
#include <cstddef>
27
#include <stdexcept>
28
#include <boost/regex/v5/error_type.hpp>
29
#include <boost/regex/v5/regex_traits_defaults.hpp>
30
31
namespace boost{
32
33
#ifdef BOOST_REGEX_MSVC
34
#pragma warning(push)
35
#pragma warning(disable : 4275)
36
#if BOOST_REGEX_MSVC >= 1800
37
#pragma warning(disable : 26812 4459)
38
#endif
39
#endif
40
class regex_error : public std::runtime_error
41
{
42
public:
43
   explicit regex_error(const std::string& s, regex_constants::error_type err = regex_constants::error_unknown, std::ptrdiff_t pos = 0)
44
      : std::runtime_error(s)
45
      , m_error_code(err)
46
      , m_position(pos)
47
0
   {
48
0
   }
49
   explicit regex_error(regex_constants::error_type err)
50
      : std::runtime_error(::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err))
51
      , m_error_code(err)
52
      , m_position(0)
53
0
   {
54
0
   }
55
0
   ~regex_error() noexcept override {}
56
   regex_constants::error_type code()const
57
0
   { return m_error_code; }
58
   std::ptrdiff_t position()const
59
0
   { return m_position; }
60
   void raise()const 
61
0
   {
62
0
#ifndef BOOST_NO_EXCEPTIONS
63
0
#ifndef BOOST_REGEX_STANDALONE
64
0
      ::boost::throw_exception(*this);
65
#else
66
      throw* this;
67
#endif
68
0
#endif
69
0
   }
70
private:
71
   regex_constants::error_type m_error_code;
72
   std::ptrdiff_t m_position;
73
};
74
75
typedef regex_error bad_pattern;
76
typedef regex_error bad_expression;
77
78
namespace BOOST_REGEX_DETAIL_NS{
79
80
inline void raise_runtime_error(const std::runtime_error& ex)
81
0
{
82
0
#ifndef BOOST_REGEX_STANDALONE
83
0
   ::boost::throw_exception(ex);
84
#else
85
   throw ex;
86
#endif
87
0
}
88
89
template <class traits>
90
void raise_error(const traits& t, regex_constants::error_type code)
91
0
{
92
0
   (void)t;  // warning suppression
93
0
   std::runtime_error e(t.error_string(code));
94
0
   ::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(e);
95
0
}
96
97
}
98
99
#ifdef BOOST_REGEX_MSVC
100
#pragma warning(pop)
101
#endif
102
103
} // namespace boost
104
105
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/perl_matcher.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
#ifndef BOOST_REGEX_MATCHER_HPP
13
#define BOOST_REGEX_MATCHER_HPP
14
15
#include <boost/regex/v5/iterator_category.hpp>
16
17
#ifdef BOOST_REGEX_MSVC
18
#  pragma warning(push)
19
#pragma warning(disable : 4251 4459)
20
#if BOOST_REGEX_MSVC < 1700
21
#     pragma warning(disable : 4231)
22
#endif
23
#  if BOOST_REGEX_MSVC < 1600
24
#     pragma warning(disable : 4660)
25
#  endif
26
#if BOOST_REGEX_MSVC < 1910
27
#pragma warning(disable:4800)
28
#endif
29
#endif
30
31
namespace boost{
32
namespace BOOST_REGEX_DETAIL_NS{
33
34
//
35
// error checking API:
36
//
37
inline void  verify_options(boost::regex_constants::syntax_option_type, match_flag_type mf)
38
5
{
39
   //
40
   // can't mix match_extra with POSIX matching rules:
41
   //
42
5
   if ((mf & match_extra) && (mf & match_posix))
43
0
   {
44
0
      std::logic_error msg("Usage Error: Can't mix regular expression captures with POSIX matching rules");
45
0
#ifndef BOOST_REGEX_STANDALONE
46
0
      throw_exception(msg);
47
#else
48
      throw msg;
49
#endif
50
0
   }
51
5
}
52
//
53
// function can_start:
54
//
55
template <class charT>
56
inline bool can_start(charT c, const unsigned char* map, unsigned char mask)
57
{
58
   return ((c < static_cast<charT>(0)) ? true : ((c >= static_cast<charT>(1 << CHAR_BIT)) ? true : map[c] & mask));
59
}
60
inline bool can_start(char c, const unsigned char* map, unsigned char mask)
61
54
{
62
54
   return map[(unsigned char)c] & mask;
63
54
}
64
inline bool can_start(signed char c, const unsigned char* map, unsigned char mask)
65
0
{
66
0
   return map[(unsigned char)c] & mask;
67
0
}
68
inline bool can_start(unsigned char c, const unsigned char* map, unsigned char mask)
69
0
{
70
0
   return map[c] & mask;
71
0
}
72
inline bool can_start(unsigned short c, const unsigned char* map, unsigned char mask)
73
0
{
74
0
   return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);
75
0
}
76
#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
77
inline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask)
78
{
79
   return ((c >= static_cast<wchar_t>(1u << CHAR_BIT)) ? true : map[c] & mask);
80
}
81
#endif
82
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
83
inline bool can_start(unsigned int c, const unsigned char* map, unsigned char mask)
84
0
{
85
0
   return (((c >= static_cast<unsigned int>(1u << CHAR_BIT)) ? true : map[c] & mask));
86
0
}
87
#endif
88
89
template <class C, class T, class A>
90
inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
91
0
{ 
92
0
   if(0 == *p)
93
0
   {
94
0
      if(s.empty() || ((s.size() == 1) && (s[0] == 0)))
95
0
         return 0;
96
0
   }
97
0
   return s.compare(p); 
98
0
}
99
template <class Seq, class C>
100
inline int string_compare(const Seq& s, const C* p)
101
{
102
   std::size_t i = 0;
103
   while((i < s.size()) && (p[i] == s[i]))
104
   {
105
      ++i;
106
   }
107
   return (i == s.size()) ? -(int)p[i] : (int)s[i] - (int)p[i];
108
}
109
0
# define STR_COMP(s,p) string_compare(s,p)
110
111
template<class charT>
112
inline const charT* re_skip_past_null(const charT* p)
113
0
{
114
0
  while (*p != static_cast<charT>(0)) ++p;
115
0
  return ++p;
116
0
}
117
118
template <class iterator, class charT, class traits_type, class char_classT>
119
iterator  re_is_set_member(iterator next, 
120
                          iterator last, 
121
                          const re_set_long<char_classT>* set_, 
122
                          const regex_data<charT, traits_type>& e, bool icase)
123
0
{   
124
0
   const charT* p = reinterpret_cast<const charT*>(set_+1);
125
0
   iterator ptr;
126
0
   unsigned int i;
127
   //bool icase = e.m_flags & regex_constants::icase;
128
129
0
   if(next == last) return next;
130
131
0
   typedef typename traits_type::string_type traits_string_type;
132
0
   const ::boost::regex_traits_wrapper<traits_type>& traits_inst = *(e.m_ptraits);
133
   
134
   // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
135
   // referenced
136
0
   (void)traits_inst;
137
138
   // try and match a single character, could be a multi-character
139
   // collating element...
140
0
   for(i = 0; i < set_->csingles; ++i)
141
0
   {
142
0
      ptr = next;
143
0
      if(*p == static_cast<charT>(0))
144
0
      {
145
         // treat null string as special case:
146
0
         if(traits_inst.translate(*ptr, icase))
147
0
         {
148
0
            ++p;
149
0
            continue;
150
0
         }
151
0
         return set_->isnot ? next : (ptr == next) ? ++next : ptr;
152
0
      }
153
0
      else
154
0
      {
155
0
         while(*p && (ptr != last))
156
0
         {
157
0
            if(traits_inst.translate(*ptr, icase) != *p)
158
0
               break;
159
0
            ++p;
160
0
            ++ptr;
161
0
         }
162
163
0
         if(*p == static_cast<charT>(0)) // if null we've matched
164
0
            return set_->isnot ? next : (ptr == next) ? ++next : ptr;
165
166
0
         p = re_skip_past_null(p);     // skip null
167
0
      }
168
0
   }
169
170
0
   charT col = traits_inst.translate(*next, icase);
171
172
173
0
   if(set_->cranges || set_->cequivalents)
174
0
   {
175
0
      traits_string_type s1;
176
      //
177
      // try and match a range, NB only a single character can match
178
0
      if(set_->cranges)
179
0
      {
180
0
         if((e.m_flags & regex_constants::collate) == 0)
181
0
            s1.assign(1, col);
182
0
         else
183
0
         {
184
0
            charT a[2] = { col, charT(0), };
185
0
            s1 = traits_inst.transform(a, a + 1);
186
0
         }
187
0
         for(i = 0; i < set_->cranges; ++i)
188
0
         {
189
0
            if(STR_COMP(s1, p) >= 0)
190
0
            {
191
0
               do{ ++p; }while(*p);
192
0
               ++p;
193
0
               if(STR_COMP(s1, p) <= 0)
194
0
                  return set_->isnot ? next : ++next;
195
0
            }
196
0
            else
197
0
            {
198
               // skip first string
199
0
               do{ ++p; }while(*p);
200
0
               ++p;
201
0
            }
202
            // skip second string
203
0
            do{ ++p; }while(*p);
204
0
            ++p;
205
0
         }
206
0
      }
207
      //
208
      // try and match an equivalence class, NB only a single character can match
209
0
      if(set_->cequivalents)
210
0
      {
211
0
         charT a[2] = { col, charT(0), };
212
0
         s1 = traits_inst.transform_primary(a, a +1);
213
0
         for(i = 0; i < set_->cequivalents; ++i)
214
0
         {
215
0
            if(STR_COMP(s1, p) == 0)
216
0
               return set_->isnot ? next : ++next;
217
            // skip string
218
0
            do{ ++p; }while(*p);
219
0
            ++p;
220
0
         }
221
0
      }
222
0
   }
223
0
   if(traits_inst.isctype(col, set_->cclasses) == true)
224
0
      return set_->isnot ? next : ++next;
225
0
   if((set_->cnclasses != 0) && (traits_inst.isctype(col, set_->cnclasses) == false))
226
0
      return set_->isnot ? next : ++next;
227
0
   return set_->isnot ? ++next : next;
228
0
}
Unexecuted instantiation: _ZN5boost13re_detail_50016re_is_set_memberIPccNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEjEET_S7_S7_PKNS0_11re_set_longIT2_EERKNS0_10regex_dataIT0_T1_EEb
Unexecuted instantiation: _ZN5boost13re_detail_50016re_is_set_memberINSt3__111__wrap_iterIPKcEEcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEjEET_SB_SB_PKNS0_11re_set_longIT2_EERKNS0_10regex_dataIT0_T1_EEb
229
230
template <class BidiIterator>
231
class repeater_count
232
{
233
   repeater_count** stack;
234
   repeater_count* next;
235
   int state_id;
236
   std::size_t count;        // the number of iterations so far
237
   BidiIterator start_pos;   // where the last repeat started
238
239
   repeater_count* unwind_until(int n, repeater_count* p, int current_recursion_id)
240
18
   { 
241
21
      while(p && (p->state_id != n))
242
3
      {
243
3
         if(-2 - current_recursion_id == p->state_id)
244
0
            return 0;
245
3
         p = p->next;
246
3
         if(p && (p->state_id < 0))
247
0
         {
248
0
            p = unwind_until(p->state_id, p, current_recursion_id);
249
0
            if(!p)
250
0
               return p;
251
0
            p = p->next;
252
0
         }
253
3
      }
254
18
      return p;
255
18
   }
256
public:
257
5
   repeater_count(repeater_count** s) : stack(s), next(0), state_id(-1), count(0), start_pos() {}
258
   
259
   repeater_count(int i, repeater_count** s, BidiIterator start, int current_recursion_id)
260
      : start_pos(start)
261
18
   {
262
18
      state_id = i;
263
18
      stack = s;
264
18
      next = *stack;
265
18
      *stack = this;
266
18
      if((state_id > next->state_id) && (next->state_id >= 0))
267
0
         count = 0;
268
18
      else
269
18
      {
270
18
         repeater_count* p = next;
271
18
         p = unwind_until(state_id, p, current_recursion_id);
272
18
         if(p)
273
15
         {
274
15
            count = p->count;
275
15
            start_pos = p->start_pos;
276
15
         }
277
3
         else
278
3
            count = 0;
279
18
      }
280
18
   }
281
   ~repeater_count()
282
23
   {
283
23
      if(next)
284
18
         *stack = next;
285
23
   }
286
33
   std::size_t get_count() { return count; }
287
0
   int get_id() { return state_id; }
288
15
   std::size_t operator++() { return ++count; }
289
   bool check_null_repeat(const BidiIterator& pos, std::size_t max)
290
18
   {
291
      // this is called when we are about to start a new repeat,
292
      // if the last one was NULL move our count to max,
293
      // otherwise save the current position.
294
18
      bool result = (count == 0) ? false : (pos == start_pos);
295
18
      if(result)
296
0
         count = max;
297
18
      else
298
18
         start_pos = pos;
299
18
      return result;
300
18
   }
301
};
302
303
struct saved_state;
304
305
enum saved_state_type
306
{
307
   saved_type_end = 0,
308
   saved_type_paren = 1,
309
   saved_type_recurse = 2,
310
   saved_type_assertion = 3,
311
   saved_state_alt = 4,
312
   saved_state_repeater_count = 5,
313
   saved_state_extra_block = 6,
314
   saved_state_greedy_single_repeat = 7,
315
   saved_state_rep_slow_dot = 8,
316
   saved_state_rep_fast_dot = 9,
317
   saved_state_rep_char = 10,
318
   saved_state_rep_short_set = 11,
319
   saved_state_rep_long_set = 12,
320
   saved_state_non_greedy_long_repeat = 13, 
321
   saved_state_count = 14
322
};
323
324
#ifdef BOOST_REGEX_MSVC
325
#  pragma warning(push)
326
#if BOOST_REGEX_MSVC >= 1800
327
#pragma warning(disable:26495)
328
#endif
329
#endif
330
template <class Results>
331
struct recursion_info
332
{
333
   typedef typename Results::value_type value_type;
334
   typedef typename value_type::iterator iterator;
335
   int idx;
336
   const re_syntax_base* preturn_address;
337
   Results results;
338
   repeater_count<iterator>* repeater_stack;
339
   iterator location_of_start;
340
};
341
#ifdef BOOST_REGEX_MSVC
342
#  pragma warning(pop)
343
#endif
344
345
template <class BidiIterator, class Allocator, class traits>
346
class perl_matcher
347
{
348
public:
349
   typedef typename traits::char_type char_type;
350
   typedef perl_matcher<BidiIterator, Allocator, traits> self_type;
351
   typedef bool (self_type::*matcher_proc_type)();
352
   typedef std::size_t traits_size_type;
353
   typedef typename is_byte<char_type>::width_type width_type;
354
   typedef typename std::iterator_traits<BidiIterator>::difference_type difference_type;
355
   typedef match_results<BidiIterator, Allocator> results_type;
356
357
   perl_matcher(BidiIterator first, BidiIterator end, 
358
      match_results<BidiIterator, Allocator>& what, 
359
      const basic_regex<char_type, traits>& e,
360
      match_flag_type f,
361
      BidiIterator l_base)
362
      :  m_result(what), base(first), last(end), 
363
         position(first), backstop(l_base), re(e), traits_inst(e.get_traits()), 
364
         m_independent(false), next_count(&rep_obj), rep_obj(&next_count)
365
      , m_recursions(0)
366
5
   {
367
5
      construct_init(e, f);
368
5
   }
369
370
   bool match();
371
   bool find();
372
373
   void setf(match_flag_type f)
374
   { m_match_flags |= f; }
375
   void unsetf(match_flag_type f)
376
   { m_match_flags &= ~f; }
377
378
private:
379
   void construct_init(const basic_regex<char_type, traits>& e, match_flag_type f);
380
381
   bool find_imp();
382
   bool match_imp();
383
   void estimate_max_state_count(std::random_access_iterator_tag*);
384
   void estimate_max_state_count(void*);
385
   bool match_prefix();
386
   bool match_all_states();
387
388
   // match procs, stored in s_match_vtable:
389
   bool match_startmark();
390
   bool match_endmark();
391
   bool match_literal();
392
   bool match_start_line();
393
   bool match_end_line();
394
   bool match_wild();
395
   bool match_match();
396
   bool match_word_boundary();
397
   bool match_within_word();
398
   bool match_word_start();
399
   bool match_word_end();
400
   bool match_buffer_start();
401
   bool match_buffer_end();
402
   bool match_backref();
403
   bool match_long_set();
404
   bool match_set();
405
   bool match_jump();
406
   bool match_alt();
407
   bool match_rep();
408
   bool match_combining();
409
   bool match_soft_buffer_end();
410
   bool match_restart_continue();
411
   bool match_long_set_repeat();
412
   bool match_set_repeat();
413
   bool match_char_repeat();
414
   bool match_dot_repeat_fast();
415
   bool match_dot_repeat_slow();
416
   bool match_dot_repeat_dispatch()
417
0
   {
418
0
      return ::boost::is_random_access_iterator<BidiIterator>::value ? match_dot_repeat_fast() : match_dot_repeat_slow();
419
0
   }
420
   bool match_backstep();
421
   bool match_assert_backref();
422
   bool match_toggle_case();
423
   bool match_recursion();
424
   bool match_fail();
425
   bool match_accept();
426
   bool match_commit();
427
   bool match_then();
428
   bool skip_until_paren(int index, bool match = true);
429
430
   // find procs stored in s_find_vtable:
431
   bool find_restart_any();
432
   bool find_restart_word();
433
   bool find_restart_line();
434
   bool find_restart_buf();
435
   bool find_restart_lit();
436
437
private:
438
   // final result structure to be filled in:
439
   match_results<BidiIterator, Allocator>& m_result;
440
   // temporary result for POSIX matches:
441
   std::unique_ptr<match_results<BidiIterator, Allocator> > m_temp_match;
442
   // pointer to actual result structure to fill in:
443
   match_results<BidiIterator, Allocator>* m_presult;
444
   // start of sequence being searched:
445
   BidiIterator base;
446
   // end of sequence being searched:
447
   BidiIterator last; 
448
   // current character being examined:
449
   BidiIterator position;
450
   // where to restart next search after failed match attempt:
451
   BidiIterator restart;
452
   // where the current search started from, acts as base for $` during grep:
453
   BidiIterator search_base;
454
   // how far we can go back when matching lookbehind:
455
   BidiIterator backstop;
456
   // the expression being examined:
457
   const basic_regex<char_type, traits>& re;
458
   // the expression's traits class:
459
   const ::boost::regex_traits_wrapper<traits>& traits_inst;
460
   // the next state in the machine being matched:
461
   const re_syntax_base* pstate;
462
   // matching flags in use:
463
   match_flag_type m_match_flags;
464
   // how many states we have examined so far:
465
   std::ptrdiff_t state_count;
466
   // max number of states to examine before giving up:
467
   std::ptrdiff_t max_state_count;
468
   // whether we should ignore case or not:
469
   bool icase;
470
   // set to true when (position == last), indicates that we may have a partial match:
471
   bool m_has_partial_match;
472
   // set to true whenever we get a match:
473
   bool m_has_found_match;
474
   // set to true whenever we're inside an independent sub-expression:
475
   bool m_independent;
476
   // the current repeat being examined:
477
   repeater_count<BidiIterator>* next_count;
478
   // the first repeat being examined (top of linked list):
479
   repeater_count<BidiIterator> rep_obj;
480
   // the mask to pass when matching word boundaries:
481
   typename traits::char_class_type m_word_mask;
482
   // the bitmask to use when determining whether a match_any matches a newline or not:
483
   unsigned char match_any_mask;
484
   // recursion information:
485
   std::vector<recursion_info<results_type> > recursion_stack;
486
   //
487
   // additional members for non-recursive version:
488
   //
489
   typedef bool (self_type::*unwind_proc_type)(bool);
490
491
   void extend_stack();
492
   bool unwind(bool);
493
   bool unwind_end(bool);
494
   bool unwind_paren(bool);
495
   bool unwind_recursion_stopper(bool);
496
   bool unwind_assertion(bool);
497
   bool unwind_alt(bool);
498
   bool unwind_repeater_counter(bool);
499
   bool unwind_extra_block(bool);
500
   bool unwind_greedy_single_repeat(bool);
501
   bool unwind_slow_dot_repeat(bool);
502
   bool unwind_fast_dot_repeat(bool);
503
   bool unwind_char_repeat(bool);
504
   bool unwind_short_set_repeat(bool);
505
   bool unwind_long_set_repeat(bool);
506
   bool unwind_non_greedy_repeat(bool);
507
   bool unwind_recursion(bool);
508
   bool unwind_recursion_pop(bool);
509
   bool unwind_commit(bool);
510
   bool unwind_then(bool);
511
   bool unwind_case(bool);
512
   void destroy_single_repeat();
513
   void push_matched_paren(int index, const sub_match<BidiIterator>& sub);
514
   void push_recursion_stopper();
515
   void push_assertion(const re_syntax_base* ps, bool positive);
516
   void push_alt(const re_syntax_base* ps);
517
   void push_repeater_count(int i, repeater_count<BidiIterator>** s);
518
   void push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id);
519
   void push_non_greedy_repeat(const re_syntax_base* ps);
520
   void push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2);
521
   void push_recursion_pop();
522
   void push_case_change(bool);
523
524
   // pointer to base of stack:
525
   saved_state* m_stack_base;
526
   // pointer to current stack position:
527
   saved_state* m_backup_state;
528
   // how many memory blocks have we used up?:
529
   unsigned used_block_count;
530
   // determines what value to return when unwinding from recursion,
531
   // allows for mixed recursive/non-recursive algorithm:
532
   bool m_recursive_result;
533
   // We have unwound to a lookahead/lookbehind, used by COMMIT/PRUNE/SKIP:
534
   bool m_unwound_lookahead;
535
   // We have unwound to an alternative, used by THEN:
536
   bool m_unwound_alt;
537
   // We are unwinding a commit - used by independent subs to determine whether to stop there or carry on unwinding:
538
   //bool m_unwind_commit;
539
   // Recursion limit:
540
   unsigned m_recursions;
541
542
#ifdef BOOST_REGEX_MSVC
543
#  pragma warning(push)
544
#if BOOST_REGEX_MSVC >= 1800
545
#pragma warning(disable:26495)
546
#endif
547
#endif
548
   // these operations aren't allowed, so are declared private,
549
   // bodies are provided to keep explicit-instantiation requests happy:
550
   perl_matcher& operator=(const perl_matcher&)
551
   {
552
      return *this;
553
   }
554
   perl_matcher(const perl_matcher& that)
555
      : m_result(that.m_result), re(that.re), traits_inst(that.traits_inst), rep_obj(0) {}
556
#ifdef BOOST_REGEX_MSVC
557
#  pragma warning(pop)
558
#endif
559
};
560
561
} // namespace BOOST_REGEX_DETAIL_NS
562
563
#ifdef BOOST_REGEX_MSVC
564
#  pragma warning(pop)
565
#endif
566
567
} // namespace boost
568
569
//
570
// include the implementation of perl_matcher:
571
//
572
#include <boost/regex/v5/perl_matcher_non_recursive.hpp>
573
// this one has to be last:
574
#include <boost/regex/v5/perl_matcher_common.hpp>
575
576
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/perl_matcher_common.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         perl_matcher_common.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Definitions of perl_matcher member functions that are 
17
  *                common to both the recursive and non-recursive versions.
18
  */
19
20
#ifndef BOOST_REGEX_V5_PERL_MATCHER_COMMON_HPP
21
#define BOOST_REGEX_V5_PERL_MATCHER_COMMON_HPP
22
23
#ifdef BOOST_REGEX_MSVC
24
#  pragma warning(push)
25
#pragma warning(disable:4459)
26
#if BOOST_REGEX_MSVC < 1910
27
#pragma warning(disable:4800)
28
#endif
29
#endif
30
31
namespace boost{
32
namespace BOOST_REGEX_DETAIL_NS{
33
34
#ifdef BOOST_REGEX_MSVC
35
#  pragma warning(push)
36
#pragma warning(disable:26812)
37
#endif
38
   template <class BidiIterator, class Allocator, class traits>
39
void perl_matcher<BidiIterator, Allocator, traits>::construct_init(const basic_regex<char_type, traits>& e, match_flag_type f)
40
5
{ 
41
5
   typedef typename std::iterator_traits<BidiIterator>::iterator_category category;
42
5
   typedef typename basic_regex<char_type, traits>::flag_type expression_flag_type;
43
   
44
5
   if(e.empty())
45
0
   {
46
      // precondition failure: e is not a valid regex.
47
0
      std::invalid_argument ex("Invalid regular expression object");
48
0
#ifndef BOOST_REGEX_STANDALONE
49
0
      boost::throw_exception(ex);
50
#else
51
      throw e;
52
#endif
53
0
   }
54
5
   pstate = 0;
55
5
   m_match_flags = f;
56
5
   estimate_max_state_count(static_cast<category*>(0));
57
5
   expression_flag_type re_f = re.flags();
58
5
   icase = re_f & regex_constants::icase;
59
5
   if(!(m_match_flags & (match_perl|match_posix)))
60
5
   {
61
5
      if((re_f & (regbase::main_option_type|regbase::no_perl_ex)) == 0)
62
5
         m_match_flags |= match_perl;
63
0
      else if((re_f & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
64
0
         m_match_flags |= match_perl;
65
0
      else if((re_f & (regbase::main_option_type|regbase::literal)) == (regbase::literal))
66
0
         m_match_flags |= match_perl;
67
0
      else
68
0
         m_match_flags |= match_posix;
69
5
   }
70
5
   if(m_match_flags & match_posix)
71
0
   {
72
0
      m_temp_match.reset(new match_results<BidiIterator, Allocator>());
73
0
      m_presult = m_temp_match.get();
74
0
   }
75
5
   else
76
5
      m_presult = &m_result;
77
5
   m_stack_base = 0;
78
5
   m_backup_state = 0;
79
   // find the value to use for matching word boundaries:
80
5
   m_word_mask = re.get_data().m_word_mask; 
81
   // find bitmask to use for matching '.':
82
5
   match_any_mask = static_cast<unsigned char>((f & match_not_dot_newline) ? BOOST_REGEX_DETAIL_NS::test_not_newline : BOOST_REGEX_DETAIL_NS::test_newline);
83
   // Disable match_any if requested in the state machine:
84
5
   if(e.get_data().m_disable_match_any)
85
0
      m_match_flags &= regex_constants::match_not_any;
86
5
}
87
#ifdef BOOST_REGEX_MSVC
88
#  pragma warning(pop)
89
#endif
90
91
template <class BidiIterator, class Allocator, class traits>
92
void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)
93
5
{
94
   //
95
   // How many states should we allow our machine to visit before giving up?
96
   // This is a heuristic: it takes the greater of O(N^2) and O(NS^2)
97
   // where N is the length of the string, and S is the number of states
98
   // in the machine.  It's tempting to up this to O(N^2S) or even O(N^2S^2)
99
   // but these take unreasonably amounts of time to bale out in pathological
100
   // cases.
101
   //
102
   // Calculate NS^2 first:
103
   //
104
5
   static const std::ptrdiff_t k = 100000;
105
5
   std::ptrdiff_t dist = std::distance(base, last);
106
5
   if(dist == 0)
107
2
      dist = 1;
108
5
   std::ptrdiff_t states = re.size();
109
5
   if(states == 0)
110
0
      states = 1;
111
5
   if ((std::numeric_limits<std::ptrdiff_t>::max)() / states < states)
112
0
   {
113
0
      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
114
0
      return;
115
0
   }
116
5
   states *= states;
117
5
   if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
118
0
   {
119
0
      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
120
0
      return;
121
0
   }
122
5
   states *= dist;
123
5
   if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
124
0
   {
125
0
      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
126
0
      return;
127
0
   }
128
5
   states += k;
129
130
5
   max_state_count = states;
131
132
   //
133
   // Now calculate N^2:
134
   //
135
5
   states = dist;
136
5
   if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
137
0
   {
138
0
      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
139
0
      return;
140
0
   }
141
5
   states *= dist;
142
5
   if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
143
0
   {
144
0
      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
145
0
      return;
146
0
   }
147
5
   states += k;
148
   //
149
   // N^2 can be a very large number indeed, to prevent things getting out
150
   // of control, cap the max states:
151
   //
152
5
   if(states > BOOST_REGEX_MAX_STATE_COUNT)
153
0
      states = BOOST_REGEX_MAX_STATE_COUNT;
154
   //
155
   // If (the possibly capped) N^2 is larger than our first estimate,
156
   // use this instead:
157
   //
158
5
   if(states > max_state_count)
159
0
      max_state_count = states;
160
5
}
161
162
template <class BidiIterator, class Allocator, class traits>
163
inline void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)
164
{
165
   // we don't know how long the sequence is:
166
   max_state_count = BOOST_REGEX_MAX_STATE_COUNT;
167
}
168
169
template <class BidiIterator, class Allocator, class traits>
170
inline bool perl_matcher<BidiIterator, Allocator, traits>::match()
171
5
{
172
5
   return match_imp();
173
5
}
174
175
template <class BidiIterator, class Allocator, class traits>
176
bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
177
5
{
178
   // initialise our stack if we are non-recursive:
179
5
   save_state_init init(&m_stack_base, &m_backup_state);
180
5
   used_block_count = BOOST_REGEX_MAX_BLOCKS;
181
5
#if !defined(BOOST_NO_EXCEPTIONS)
182
5
   try{
183
5
#endif
184
185
   // reset our state machine:
186
5
   position = base;
187
5
   search_base = base;
188
5
   state_count = 0;
189
5
   m_match_flags |= regex_constants::match_all;
190
5
   m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);
191
5
   m_presult->set_base(base);
192
5
   m_presult->set_named_subs(this->re.get_named_subs());
193
5
   if(m_match_flags & match_posix)
194
0
      m_result = *m_presult;
195
5
   verify_options(re.flags(), m_match_flags);
196
5
   if(0 == match_prefix())
197
2
      return false;
198
3
   return (m_result[0].second == last) && (m_result[0].first == base);
199
200
5
#if !defined(BOOST_NO_EXCEPTIONS)
201
5
   }
202
5
   catch(...)
203
5
   {
204
      // unwind all pushed states, apart from anything else this
205
      // ensures that all the states are correctly destructed
206
      // not just the memory freed.
207
0
      while(unwind(true)){}
208
0
      throw;
209
0
   }
210
5
#endif
211
5
}
212
213
template <class BidiIterator, class Allocator, class traits>
214
inline bool perl_matcher<BidiIterator, Allocator, traits>::find()
215
{
216
   return find_imp();
217
}
218
219
template <class BidiIterator, class Allocator, class traits>
220
bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
221
{
222
   static matcher_proc_type const s_find_vtable[7] = 
223
   {
224
      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,
225
      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,
226
      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,
227
      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,
228
      &perl_matcher<BidiIterator, Allocator, traits>::match_prefix,
229
      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
230
      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
231
   };
232
233
   // initialise our stack if we are non-recursive:
234
   save_state_init init(&m_stack_base, &m_backup_state);
235
   used_block_count = BOOST_REGEX_MAX_BLOCKS;
236
#if !defined(BOOST_NO_EXCEPTIONS)
237
   try{
238
#endif
239
240
   state_count = 0;
241
   if((m_match_flags & regex_constants::match_init) == 0)
242
   {
243
      // reset our state machine:
244
      search_base = position = base;
245
      pstate = re.get_first_state();
246
      m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);
247
      m_presult->set_base(base);
248
      m_presult->set_named_subs(this->re.get_named_subs());
249
      m_match_flags |= regex_constants::match_init;
250
   }
251
   else
252
   {
253
      // start again:
254
      search_base = position = m_result[0].second;
255
      // If last match was null and match_not_null was not set then increment
256
      // our start position, otherwise we go into an infinite loop:
257
      if(((m_match_flags & match_not_null) == 0) && (m_result.length() == 0))
258
      {
259
         if(position == last)
260
            return false;
261
         else 
262
            ++position;
263
      }
264
      // reset $` start:
265
      m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);
266
      //if((base != search_base) && (base == backstop))
267
      //   m_match_flags |= match_prev_avail;
268
   }
269
   if(m_match_flags & match_posix)
270
   {
271
      m_result.set_size(static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);
272
      m_result.set_base(base);
273
   }
274
275
   verify_options(re.flags(), m_match_flags);
276
   // find out what kind of expression we have:
277
   unsigned type = (m_match_flags & match_continuous) ? 
278
      static_cast<unsigned int>(regbase::restart_continue) 
279
         : static_cast<unsigned int>(re.get_restart_type());
280
281
   // call the appropriate search routine:
282
   matcher_proc_type proc = s_find_vtable[type];
283
   return (this->*proc)();
284
285
#if !defined(BOOST_NO_EXCEPTIONS)
286
   }
287
   catch(...)
288
   {
289
      // unwind all pushed states, apart from anything else this
290
      // ensures that all the states are correctly destructed
291
      // not just the memory freed.
292
      while(unwind(true)){}
293
      throw;
294
   }
295
#endif
296
}
297
298
template <class BidiIterator, class Allocator, class traits>
299
bool perl_matcher<BidiIterator, Allocator, traits>::match_prefix()
300
5
{
301
5
   m_has_partial_match = false;
302
5
   m_has_found_match = false;
303
5
   pstate = re.get_first_state();
304
5
   m_presult->set_first(position);
305
5
   restart = position;
306
5
   match_all_states();
307
5
   if(!m_has_found_match && m_has_partial_match && (m_match_flags & match_partial))
308
0
   {
309
0
      m_has_found_match = true;
310
0
      m_presult->set_second(last, 0, false);
311
0
      position = last;
312
0
      if((m_match_flags & match_posix) == match_posix)
313
0
      {
314
0
         m_result.maybe_assign(*m_presult);
315
0
      }
316
0
   }
317
#ifdef BOOST_REGEX_MATCH_EXTRA
318
   if(m_has_found_match && (match_extra & m_match_flags))
319
   {
320
      //
321
      // we have a match, reverse the capture information:
322
      //
323
      for(unsigned i = 0; i < m_presult->size(); ++i)
324
      {
325
         typename sub_match<BidiIterator>::capture_sequence_type & seq = ((*m_presult)[i]).get_captures();
326
         std::reverse(seq.begin(), seq.end());
327
      }
328
   }
329
#endif
330
5
   if(!m_has_found_match)
331
2
      position = restart; // reset search postion
332
5
   return m_has_found_match;
333
5
}
334
335
template <class BidiIterator, class Allocator, class traits>
336
bool perl_matcher<BidiIterator, Allocator, traits>::match_literal()
337
35
{
338
35
   unsigned int len = static_cast<const re_literal*>(pstate)->length;
339
35
   const char_type* what = reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
340
   //
341
   // compare string with what we stored in
342
   // our records:
343
68
   for(unsigned int i = 0; i < len; ++i, ++position)
344
35
   {
345
35
      if((position == last) || (traits_inst.translate(*position, icase) != what[i]))
346
2
         return false;
347
35
   }
348
33
   pstate = pstate->next.p;
349
33
   return true;
350
35
}
351
352
template <class BidiIterator, class Allocator, class traits>
353
bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()
354
5
{
355
5
   if(position == backstop)
356
5
   {
357
5
      if((m_match_flags & match_prev_avail) == 0)
358
5
      {
359
5
         if((m_match_flags & match_not_bol) == 0)
360
5
         {
361
5
            pstate = pstate->next.p;
362
5
            return true;
363
5
         }
364
0
         return false;
365
5
      }
366
5
   }
367
0
   else if(m_match_flags & match_single_line)
368
0
      return false;
369
370
   // check the previous value character:
371
0
   BidiIterator t(position);
372
0
   --t;
373
0
   if(position != last)
374
0
   {
375
0
      if(is_separator(*t) && !((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n'))) )
376
0
      {
377
0
         pstate = pstate->next.p;
378
0
         return true;
379
0
      }
380
0
   }
381
0
   else if(is_separator(*t))
382
0
   {
383
0
      pstate = pstate->next.p;
384
0
      return true;
385
0
   }
386
0
   return false;
387
0
}
388
389
template <class BidiIterator, class Allocator, class traits>
390
bool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()
391
3
{
392
3
   if(position != last)
393
0
   {
394
0
      if(m_match_flags & match_single_line)
395
0
         return false;
396
      // we're not yet at the end so *first is always valid:
397
0
      if(is_separator(*position))
398
0
      {
399
0
         if((position != backstop) || (m_match_flags & match_prev_avail))
400
0
         {
401
            // check that we're not in the middle of \r\n sequence
402
0
            BidiIterator t(position);
403
0
            --t;
404
0
            if((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n')))
405
0
            {
406
0
               return false;
407
0
            }
408
0
         }
409
0
         pstate = pstate->next.p;
410
0
         return true;
411
0
      }
412
0
   }
413
3
   else if((m_match_flags & match_not_eol) == 0)
414
3
   {
415
3
      pstate = pstate->next.p;
416
3
      return true;
417
3
   }
418
0
   return false;
419
3
}
420
421
template <class BidiIterator, class Allocator, class traits>
422
bool perl_matcher<BidiIterator, Allocator, traits>::match_wild()
423
0
{
424
0
   if(position == last) 
425
0
      return false;
426
0
   if(is_separator(*position) && ((match_any_mask & static_cast<const re_dot*>(pstate)->mask) == 0))
427
0
      return false;
428
0
   if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))
429
0
      return false;
430
0
   pstate = pstate->next.p;
431
0
   ++position;
432
0
   return true;
433
0
}
434
435
template <class BidiIterator, class Allocator, class traits>
436
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
437
0
{
438
0
   bool b; // indcates whether next character is a word character
439
0
   if(position != last)
440
0
   {
441
      // prev and this character must be opposites:
442
0
      b = traits_inst.isctype(*position, m_word_mask);
443
0
   }
444
0
   else
445
0
   {
446
0
      if (m_match_flags & match_not_eow)
447
0
         return false;
448
0
      b = false;
449
0
   }
450
0
   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
451
0
   {
452
0
      if(m_match_flags & match_not_bow)
453
0
         return false;
454
0
      else
455
0
         b ^= false;
456
0
   }
457
0
   else
458
0
   {
459
0
      --position;
460
0
      b ^= traits_inst.isctype(*position, m_word_mask);
461
0
      ++position;
462
0
   }
463
0
   if(b)
464
0
   {
465
0
      pstate = pstate->next.p;
466
0
      return true;
467
0
   }
468
0
   return false; // no match if we get to here...
469
0
}
470
471
template <class BidiIterator, class Allocator, class traits>
472
bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
473
0
{
474
0
   if(position == last)
475
0
      return false;
476
   // both prev and this character must be m_word_mask:
477
0
   bool prev = traits_inst.isctype(*position, m_word_mask);
478
0
   {
479
0
      bool b;
480
0
      if((position == backstop) && ((m_match_flags & match_prev_avail) == 0)) 
481
0
         return false;
482
0
      else
483
0
      {
484
0
         --position;
485
0
         b = traits_inst.isctype(*position, m_word_mask);
486
0
         ++position;
487
0
      }
488
0
      if(b == prev)
489
0
      {
490
0
         pstate = pstate->next.p;
491
0
         return true;
492
0
      }
493
0
   }
494
0
   return false;
495
0
}
496
497
template <class BidiIterator, class Allocator, class traits>
498
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
499
0
{
500
0
   if(position == last)
501
0
      return false; // can't be starting a word if we're already at the end of input
502
0
   if(!traits_inst.isctype(*position, m_word_mask))
503
0
      return false; // next character isn't a word character
504
0
   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
505
0
   {
506
0
      if(m_match_flags & match_not_bow)
507
0
         return false; // no previous input
508
0
   }
509
0
   else
510
0
   {
511
      // otherwise inside buffer:
512
0
      BidiIterator t(position);
513
0
      --t;
514
0
      if(traits_inst.isctype(*t, m_word_mask))
515
0
         return false; // previous character not non-word
516
0
   }
517
   // OK we have a match:
518
0
   pstate = pstate->next.p;
519
0
   return true;
520
0
}
521
522
template <class BidiIterator, class Allocator, class traits>
523
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
524
0
{
525
0
   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
526
0
      return false;  // start of buffer can't be end of word
527
0
   BidiIterator t(position);
528
0
   --t;
529
0
   if(traits_inst.isctype(*t, m_word_mask) == false)
530
0
      return false;  // previous character wasn't a word character
531
532
0
   if(position == last)
533
0
   {
534
0
      if(m_match_flags & match_not_eow)
535
0
         return false; // end of buffer but not end of word
536
0
   }
537
0
   else
538
0
   {
539
      // otherwise inside buffer:
540
0
      if(traits_inst.isctype(*position, m_word_mask))
541
0
         return false; // next character is a word character
542
0
   }
543
0
   pstate = pstate->next.p;
544
0
   return true;      // if we fall through to here then we've succeeded
545
0
}
546
547
template <class BidiIterator, class Allocator, class traits>
548
bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()
549
0
{
550
0
   if((position != backstop) || (m_match_flags & match_not_bob))
551
0
      return false;
552
   // OK match:
553
0
   pstate = pstate->next.p;
554
0
   return true;
555
0
}
556
557
template <class BidiIterator, class Allocator, class traits>
558
bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end()
559
0
{
560
0
   if((position != last) || (m_match_flags & match_not_eob))
561
0
      return false;
562
   // OK match:
563
0
   pstate = pstate->next.p;
564
0
   return true;
565
0
}
566
567
template <class BidiIterator, class Allocator, class traits>
568
bool perl_matcher<BidiIterator, Allocator, traits>::match_backref()
569
0
{
570
   //
571
   // Compare with what we previously matched.
572
   // Note that this succeeds if the backref did not partisipate
573
   // in the match, this is in line with ECMAScript, but not Perl
574
   // or PCRE.
575
   //
576
0
   int index = static_cast<const re_brace*>(pstate)->index;
577
0
   if(index >= hash_value_mask)
578
0
   {
579
0
      named_subexpressions::range_type r = re.get_data().equal_range(index);
580
0
      BOOST_REGEX_ASSERT(r.first != r.second);
581
0
      do
582
0
      {
583
0
         index = r.first->index;
584
0
         ++r.first;
585
0
      }while((r.first != r.second) && ((*m_presult)[index].matched != true));
586
0
   }
587
588
0
   if((m_match_flags & match_perl) && !(*m_presult)[index].matched)
589
0
      return false;
590
591
0
   BidiIterator i = (*m_presult)[index].first;
592
0
   BidiIterator j = (*m_presult)[index].second;
593
0
   while(i != j)
594
0
   {
595
0
      if((position == last) || (traits_inst.translate(*position, icase) != traits_inst.translate(*i, icase)))
596
0
         return false;
597
0
      ++i;
598
0
      ++position;
599
0
   }
600
0
   pstate = pstate->next.p;
601
0
   return true;
602
0
}
603
604
template <class BidiIterator, class Allocator, class traits>
605
bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()
606
0
{
607
0
   typedef typename traits::char_class_type char_class_type;
608
   // let the traits class do the work:
609
0
   if(position == last)
610
0
      return false;
611
0
   BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data(), icase);
612
0
   if(t != position)
613
0
   {
614
0
      pstate = pstate->next.p;
615
0
      position = t;
616
0
      return true;
617
0
   }
618
0
   return false;
619
0
}
620
621
template <class BidiIterator, class Allocator, class traits>
622
bool perl_matcher<BidiIterator, Allocator, traits>::match_set()
623
0
{
624
0
   if(position == last)
625
0
      return false;
626
0
   if(static_cast<const re_set*>(pstate)->_map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
627
0
   {
628
0
      pstate = pstate->next.p;
629
0
      ++position;
630
0
      return true;
631
0
   }
632
0
   return false;
633
0
}
634
635
template <class BidiIterator, class Allocator, class traits>
636
bool perl_matcher<BidiIterator, Allocator, traits>::match_jump()
637
15
{
638
15
   pstate = static_cast<const re_jump*>(pstate)->alt.p;
639
15
   return true;
640
15
}
641
642
template <class BidiIterator, class Allocator, class traits>
643
bool perl_matcher<BidiIterator, Allocator, traits>::match_combining()
644
0
{
645
0
   if(position == last)
646
0
      return false;
647
0
   if(is_combining(traits_inst.translate(*position, icase)))
648
0
      return false;
649
0
   ++position;
650
0
   while((position != last) && is_combining(traits_inst.translate(*position, icase)))
651
0
      ++position;
652
0
   pstate = pstate->next.p;
653
0
   return true;
654
0
}
655
656
template <class BidiIterator, class Allocator, class traits>
657
bool perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end()
658
0
{
659
0
   if(m_match_flags & match_not_eob)
660
0
      return false;
661
0
   BidiIterator p(position);
662
0
   while((p != last) && is_separator(traits_inst.translate(*p, icase)))++p;
663
0
   if(p != last)
664
0
      return false;
665
0
   pstate = pstate->next.p;
666
0
   return true;
667
0
}
668
669
template <class BidiIterator, class Allocator, class traits>
670
bool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()
671
0
{
672
0
   if(position == search_base)
673
0
   {
674
0
      pstate = pstate->next.p;
675
0
      return true;
676
0
   }
677
0
   return false;
678
0
}
679
680
template <class BidiIterator, class Allocator, class traits>
681
bool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()
682
0
{
683
#ifdef BOOST_REGEX_MSVC
684
#pragma warning(push)
685
#pragma warning(disable:4127)
686
#endif
687
0
   if( ::boost::is_random_access_iterator<BidiIterator>::value)
688
0
   {
689
0
      std::ptrdiff_t maxlen = std::distance(backstop, position);
690
0
      if(maxlen < static_cast<const re_brace*>(pstate)->index)
691
0
         return false;
692
0
      std::advance(position, -static_cast<const re_brace*>(pstate)->index);
693
0
   }
694
0
   else
695
0
   {
696
0
      int c = static_cast<const re_brace*>(pstate)->index;
697
0
      while(c--)
698
0
      {
699
0
         if(position == backstop)
700
0
            return false;
701
0
         --position;
702
0
      }
703
0
   }
704
0
   pstate = pstate->next.p;
705
0
   return true;
706
#ifdef BOOST_REGEX_MSVC
707
#pragma warning(pop)
708
#endif
709
0
}
710
711
template <class BidiIterator, class Allocator, class traits>
712
inline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref()
713
0
{
714
   // return true if marked sub-expression N has been matched:
715
0
   int index = static_cast<const re_brace*>(pstate)->index;
716
0
   bool result = false;
717
0
   if(index == 9999)
718
0
   {
719
      // Magic value for a (DEFINE) block:
720
0
      return false;
721
0
   }
722
0
   else if(index > 0)
723
0
   {
724
      // Have we matched subexpression "index"?
725
      // Check if index is a hash value:
726
0
      if(index >= hash_value_mask)
727
0
      {
728
0
         named_subexpressions::range_type r = re.get_data().equal_range(index);
729
0
         while(r.first != r.second)
730
0
         {
731
0
            if((*m_presult)[r.first->index].matched)
732
0
            {
733
0
               result = true;
734
0
               break;
735
0
            }
736
0
            ++r.first;
737
0
         }
738
0
      }
739
0
      else
740
0
      {
741
0
         result = (*m_presult)[index].matched;
742
0
      }
743
0
      pstate = pstate->next.p;
744
0
   }
745
0
   else
746
0
   {
747
      // Have we recursed into subexpression "index"?
748
      // If index == 0 then check for any recursion at all, otherwise for recursion to -index-1.
749
0
      int idx = -(index+1);
750
0
      if(idx >= hash_value_mask)
751
0
      {
752
0
         named_subexpressions::range_type r = re.get_data().equal_range(idx);
753
0
         int stack_index = recursion_stack.empty() ? -1 : recursion_stack.back().idx;
754
0
         while(r.first != r.second)
755
0
         {
756
0
            result |= (stack_index == r.first->index);
757
0
            if(result)break;
758
0
            ++r.first;
759
0
         }
760
0
      }
761
0
      else
762
0
      {
763
0
         result = !recursion_stack.empty() && ((recursion_stack.back().idx == idx) || (index == 0));
764
0
      }
765
0
      pstate = pstate->next.p;
766
0
   }
767
0
   return result;
768
0
}
769
770
template <class BidiIterator, class Allocator, class traits>
771
bool perl_matcher<BidiIterator, Allocator, traits>::match_fail()
772
0
{
773
   // Just force a backtrack:
774
0
   return false;
775
0
}
776
777
template <class BidiIterator, class Allocator, class traits>
778
bool perl_matcher<BidiIterator, Allocator, traits>::match_accept()
779
0
{
780
0
   if(!recursion_stack.empty())
781
0
   {
782
0
      return skip_until_paren(recursion_stack.back().idx);
783
0
   }
784
0
   else
785
0
   {
786
0
      return skip_until_paren(INT_MAX);
787
0
   }
788
0
}
789
790
template <class BidiIterator, class Allocator, class traits>
791
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
792
{
793
#ifdef BOOST_REGEX_MSVC
794
#pragma warning(push)
795
#pragma warning(disable:4127)
796
#endif
797
   const unsigned char* _map = re.get_map();
798
   while(true)
799
   {
800
      // skip everything we can't match:
801
      while((position != last) && !can_start(*position, _map, (unsigned char)mask_any) )
802
         ++position;
803
      if(position == last)
804
      {
805
         // run out of characters, try a null match if possible:
806
         if(re.can_be_null())
807
            return match_prefix();
808
         break;
809
      }
810
      // now try and obtain a match:
811
      if(match_prefix())
812
         return true;
813
      if(position == last)
814
         return false;
815
      ++position;
816
   }
817
   return false;
818
#ifdef BOOST_REGEX_MSVC
819
#pragma warning(pop)
820
#endif
821
}
822
823
template <class BidiIterator, class Allocator, class traits>
824
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()
825
{
826
#ifdef BOOST_REGEX_MSVC
827
#pragma warning(push)
828
#pragma warning(disable:4127)
829
#endif
830
   // do search optimised for word starts:
831
   const unsigned char* _map = re.get_map();
832
   if((m_match_flags & match_prev_avail) || (position != base))
833
      --position;
834
   else if(match_prefix())
835
      return true;
836
   do
837
   {
838
      while((position != last) && traits_inst.isctype(*position, m_word_mask))
839
         ++position;
840
      while((position != last) && !traits_inst.isctype(*position, m_word_mask))
841
         ++position;
842
      if(position == last)
843
         break;
844
845
      if(can_start(*position, _map, (unsigned char)mask_any) )
846
      {
847
         if(match_prefix())
848
            return true;
849
      }
850
      if(position == last)
851
         break;
852
   } while(true);
853
   return false;
854
#ifdef BOOST_REGEX_MSVC
855
#pragma warning(pop)
856
#endif
857
}
858
859
template <class BidiIterator, class Allocator, class traits>
860
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_line()
861
{
862
   // do search optimised for line starts:
863
   const unsigned char* _map = re.get_map();
864
   if(match_prefix())
865
      return true;
866
   while(position != last)
867
   {
868
      while((position != last) && !is_separator(*position))
869
         ++position;
870
      if(position == last)
871
         return false;
872
      ++position;
873
      if(position == last)
874
      {
875
         if(re.can_be_null() && match_prefix())
876
            return true;
877
         return false;
878
      }
879
880
      if( can_start(*position, _map, (unsigned char)mask_any) )
881
      {
882
         if(match_prefix())
883
            return true;
884
      }
885
      if(position == last)
886
         return false;
887
      //++position;
888
   }
889
   return false;
890
}
891
892
template <class BidiIterator, class Allocator, class traits>
893
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf()
894
{
895
   if((position == base) && ((m_match_flags & match_not_bob) == 0))
896
      return match_prefix();
897
   return false;
898
}
899
900
template <class BidiIterator, class Allocator, class traits>
901
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit()
902
{
903
   return false;
904
}
905
906
} // namespace BOOST_REGEX_DETAIL_NS
907
908
} // namespace boost
909
910
#ifdef BOOST_REGEX_MSVC
911
#  pragma warning(pop)
912
#endif
913
914
#endif
915
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/perl_matcher_non_recursive.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         perl_matcher_common.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Definitions of perl_matcher member functions that are 
17
  *                specific to the non-recursive implementation.
18
  */
19
20
#ifndef BOOST_REGEX_V5_PERL_MATCHER_NON_RECURSIVE_HPP
21
#define BOOST_REGEX_V5_PERL_MATCHER_NON_RECURSIVE_HPP
22
23
#include <boost/regex/v5/mem_block_cache.hpp>
24
25
#ifdef BOOST_REGEX_MSVC
26
#  pragma warning(push)
27
#  pragma warning(disable: 4706 4459)
28
#if BOOST_REGEX_MSVC < 1910
29
#pragma warning(disable:4800)
30
#endif
31
#endif
32
33
namespace boost{
34
namespace BOOST_REGEX_DETAIL_NS{
35
36
template <class T>
37
inline void inplace_destroy(T* p)
38
53
{
39
53
   (void)p;  // warning suppression
40
53
   p->~T();
41
53
}
_ZN5boost13re_detail_50015inplace_destroyINS0_19saved_matched_parenINSt3__111__wrap_iterIPKcEEEEEEvPT_
Line
Count
Source
38
15
{
39
15
   (void)p;  // warning suppression
40
15
   p->~T();
41
15
}
_ZN5boost13re_detail_50015inplace_destroyINS0_11saved_stateEEEvPT_
Line
Count
Source
38
5
{
39
5
   (void)p;  // warning suppression
40
5
   p->~T();
41
5
}
Unexecuted instantiation: _ZN5boost13re_detail_50015inplace_destroyINS0_15saved_assertionINSt3__111__wrap_iterIPKcEEEEEEvPT_
Unexecuted instantiation: _ZN5boost13re_detail_50015inplace_destroyINS0_14saved_positionINSt3__111__wrap_iterIPKcEEEEEEvPT_
_ZN5boost13re_detail_50015inplace_destroyINS0_14saved_repeaterINSt3__111__wrap_iterIPKcEEEEEEvPT_
Line
Count
Source
38
18
{
39
18
   (void)p;  // warning suppression
40
18
   p->~T();
41
18
}
Unexecuted instantiation: _ZN5boost13re_detail_50015inplace_destroyINS0_17saved_extra_blockEEEvPT_
_ZN5boost13re_detail_50015inplace_destroyINS0_19saved_single_repeatINSt3__111__wrap_iterIPKcEEEEEEvPT_
Line
Count
Source
38
15
{
39
15
   (void)p;  // warning suppression
40
15
   p->~T();
41
15
}
Unexecuted instantiation: _ZN5boost13re_detail_50015inplace_destroyINS0_15saved_recursionINS_13match_resultsINSt3__111__wrap_iterIPKcEENS4_9allocatorINS_9sub_matchIS8_EEEEEEEEEEvPT_
Unexecuted instantiation: _ZN5boost13re_detail_50015inplace_destroyINS0_17saved_change_caseEEEvPT_
42
43
struct saved_state
44
{
45
   union{
46
      unsigned int state_id;
47
      // this padding ensures correct alignment on 64-bit platforms:
48
      std::size_t padding1;
49
      std::ptrdiff_t padding2;
50
      void* padding3;
51
   };
52
58
   saved_state(unsigned i) : state_id(i) {}
53
};
54
55
template <class BidiIterator>
56
struct saved_matched_paren : public saved_state
57
{
58
   int index;
59
   sub_match<BidiIterator> sub;
60
15
   saved_matched_paren(int i, const sub_match<BidiIterator>& s) : saved_state(1), index(i), sub(s){}
61
};
62
63
template <class BidiIterator>
64
struct saved_position : public saved_state
65
{
66
   const re_syntax_base* pstate;
67
   BidiIterator position;
68
0
   saved_position(const re_syntax_base* ps, BidiIterator pos, int i) : saved_state(i), pstate(ps), position(pos){}
69
};
70
71
template <class BidiIterator>
72
struct saved_assertion : public saved_position<BidiIterator>
73
{
74
   bool positive;
75
   saved_assertion(bool p, const re_syntax_base* ps, BidiIterator pos) 
76
0
      : saved_position<BidiIterator>(ps, pos, saved_type_assertion), positive(p){}
77
};
78
79
template <class BidiIterator>
80
struct saved_repeater : public saved_state
81
{
82
   repeater_count<BidiIterator> count;
83
   saved_repeater(int i, repeater_count<BidiIterator>** s, BidiIterator start, int current_recursion_id)
84
18
      : saved_state(saved_state_repeater_count), count(i, s, start, current_recursion_id){}
85
};
86
87
struct saved_extra_block : public saved_state
88
{
89
   saved_state *base, *end;
90
   saved_extra_block(saved_state* b, saved_state* e) 
91
0
      : saved_state(saved_state_extra_block), base(b), end(e) {}
92
};
93
94
struct save_state_init
95
{
96
   saved_state** stack;
97
   save_state_init(saved_state** base, saved_state** end)
98
      : stack(base)
99
5
   {
100
5
      *base = static_cast<saved_state*>(get_mem_block());
101
5
      *end = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(*base)+BOOST_REGEX_BLOCKSIZE);
102
5
      --(*end);
103
5
      (void) new (*end)saved_state(0);
104
5
      BOOST_REGEX_ASSERT(*end > *base);
105
5
   }
106
   ~save_state_init()
107
5
   {
108
5
      put_mem_block(*stack);
109
5
      *stack = 0;
110
5
   }
111
};
112
113
template <class BidiIterator>
114
struct saved_single_repeat : public saved_state
115
{
116
   std::size_t count;
117
   const re_repeat* rep;
118
   BidiIterator last_position;
119
   saved_single_repeat(std::size_t c, const re_repeat* r, BidiIterator lp, int arg_id) 
120
15
      : saved_state(arg_id), count(c), rep(r), last_position(lp){}
121
};
122
123
template <class Results>
124
struct saved_recursion : public saved_state
125
{
126
   saved_recursion(int idx, const re_syntax_base* p, Results* pr, Results* pr2) 
127
0
      : saved_state(14), recursion_id(idx), preturn_address(p), internal_results(*pr), prior_results(*pr2) {}
128
   int recursion_id;
129
   const re_syntax_base* preturn_address;
130
   Results internal_results, prior_results;
131
};
132
133
struct saved_change_case : public saved_state
134
{
135
   bool icase;
136
0
   saved_change_case(bool c) : saved_state(18), icase(c) {}
137
};
138
139
struct incrementer
140
{
141
5
   incrementer(unsigned* pu) : m_pu(pu) { ++*m_pu; }
142
5
   ~incrementer() { --*m_pu; }
143
5
   bool operator > (unsigned i) { return *m_pu > i; }
144
private:
145
   unsigned* m_pu;
146
};
147
148
template <class BidiIterator, class Allocator, class traits>
149
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
150
5
{
151
5
   static matcher_proc_type const s_match_vtable[34] = 
152
5
   {
153
5
      (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
154
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
155
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_literal,
156
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
157
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
158
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_wild,
159
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_match,
160
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
161
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
162
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
163
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
164
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
165
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
166
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_backref,
167
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
168
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_set,
169
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_jump,
170
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_alt,
171
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_rep,
172
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_combining,
173
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
174
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
175
      // Although this next line *should* be evaluated at compile time, in practice
176
      // some compilers (VC++) emit run-time initialisation which breaks thread
177
      // safety, so use a dispatch function instead:
178
      //(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
179
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,
180
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
181
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
182
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
183
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,
184
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,
185
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,
186
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,
187
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_fail,
188
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_accept,
189
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_commit,
190
5
      &perl_matcher<BidiIterator, Allocator, traits>::match_then,
191
5
   };
192
5
   incrementer inc(&m_recursions);
193
5
   if(inc > 80)
194
0
      raise_error(traits_inst, regex_constants::error_complexity);
195
5
   push_recursion_stopper();
196
5
   do{
197
132
      while(pstate)
198
129
      {
199
129
         matcher_proc_type proc = s_match_vtable[pstate->type];
200
129
         ++state_count;
201
129
         if(!(this->*proc)())
202
8
         {
203
8
            if(state_count > max_state_count)
204
0
               raise_error(traits_inst, regex_constants::error_complexity);
205
8
            if((m_match_flags & match_partial) && (position == last) && (position != search_base))
206
0
               m_has_partial_match = true;
207
8
            bool successful_unwind = unwind(false);
208
8
            if((m_match_flags & match_partial) && (position == last) && (position != search_base))
209
0
               m_has_partial_match = true;
210
8
            if(!successful_unwind)
211
2
               return m_recursive_result;
212
8
         }
213
129
      }
214
5
   }while(unwind(true));
215
3
   return m_recursive_result;
216
5
}
217
218
template <class BidiIterator, class Allocator, class traits>
219
void perl_matcher<BidiIterator, Allocator, traits>::extend_stack()
220
0
{
221
0
   if(used_block_count)
222
0
   {
223
0
      --used_block_count;
224
0
      saved_state* stack_base;
225
0
      saved_state* backup_state;
226
0
      stack_base = static_cast<saved_state*>(get_mem_block());
227
0
      backup_state = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(stack_base)+BOOST_REGEX_BLOCKSIZE);
228
0
      saved_extra_block* block = static_cast<saved_extra_block*>(backup_state);
229
0
      --block;
230
0
      (void) new (block) saved_extra_block(m_stack_base, m_backup_state);
231
0
      m_stack_base = stack_base;
232
0
      m_backup_state = block;
233
0
   }
234
0
   else
235
0
      raise_error(traits_inst, regex_constants::error_stack);
236
0
}
237
238
template <class BidiIterator, class Allocator, class traits>
239
inline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)
240
15
{
241
   //BOOST_REGEX_ASSERT(index);
242
15
   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
243
15
   --pmp;
244
15
   if(pmp < m_stack_base)
245
0
   {
246
0
      extend_stack();
247
0
      pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
248
0
      --pmp;
249
0
   }
250
15
   (void) new (pmp)saved_matched_paren<BidiIterator>(index, sub);
251
15
   m_backup_state = pmp;
252
15
}
253
254
template <class BidiIterator, class Allocator, class traits>
255
inline void perl_matcher<BidiIterator, Allocator, traits>::push_case_change(bool c)
256
0
{
257
   //BOOST_REGEX_ASSERT(index);
258
0
   saved_change_case* pmp = static_cast<saved_change_case*>(m_backup_state);
259
0
   --pmp;
260
0
   if(pmp < m_stack_base)
261
0
   {
262
0
      extend_stack();
263
0
      pmp = static_cast<saved_change_case*>(m_backup_state);
264
0
      --pmp;
265
0
   }
266
0
   (void) new (pmp)saved_change_case(c);
267
0
   m_backup_state = pmp;
268
0
}
269
270
template <class BidiIterator, class Allocator, class traits>
271
inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_stopper()
272
5
{
273
5
   saved_state* pmp = m_backup_state;
274
5
   --pmp;
275
5
   if(pmp < m_stack_base)
276
0
   {
277
0
      extend_stack();
278
0
      pmp = m_backup_state;
279
0
      --pmp;
280
0
   }
281
5
   (void) new (pmp)saved_state(saved_type_recurse);
282
5
   m_backup_state = pmp;
283
5
}
284
285
template <class BidiIterator, class Allocator, class traits>
286
inline void perl_matcher<BidiIterator, Allocator, traits>::push_assertion(const re_syntax_base* ps, bool positive)
287
0
{
288
0
   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
289
0
   --pmp;
290
0
   if(pmp < m_stack_base)
291
0
   {
292
0
      extend_stack();
293
0
      pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
294
0
      --pmp;
295
0
   }
296
0
   (void) new (pmp)saved_assertion<BidiIterator>(positive, ps, position);
297
0
   m_backup_state = pmp;
298
0
}
299
300
template <class BidiIterator, class Allocator, class traits>
301
inline void perl_matcher<BidiIterator, Allocator, traits>::push_alt(const re_syntax_base* ps)
302
0
{
303
0
   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
304
0
   --pmp;
305
0
   if(pmp < m_stack_base)
306
0
   {
307
0
      extend_stack();
308
0
      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
309
0
      --pmp;
310
0
   }
311
0
   (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_alt);
312
0
   m_backup_state = pmp;
313
0
}
314
315
template <class BidiIterator, class Allocator, class traits>
316
inline void perl_matcher<BidiIterator, Allocator, traits>::push_non_greedy_repeat(const re_syntax_base* ps)
317
0
{
318
0
   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
319
0
   --pmp;
320
0
   if(pmp < m_stack_base)
321
0
   {
322
0
      extend_stack();
323
0
      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
324
0
      --pmp;
325
0
   }
326
0
   (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_non_greedy_long_repeat);
327
0
   m_backup_state = pmp;
328
0
}
329
330
template <class BidiIterator, class Allocator, class traits>
331
inline void perl_matcher<BidiIterator, Allocator, traits>::push_repeater_count(int i, repeater_count<BidiIterator>** s)
332
18
{
333
18
   saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
334
18
   --pmp;
335
18
   if(pmp < m_stack_base)
336
0
   {
337
0
      extend_stack();
338
0
      pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
339
0
      --pmp;
340
0
   }
341
18
   (void) new (pmp)saved_repeater<BidiIterator>(i, s, position, this->recursion_stack.empty() ? (INT_MIN + 3) : this->recursion_stack.back().idx);
342
18
   m_backup_state = pmp;
343
18
}
344
345
template <class BidiIterator, class Allocator, class traits>
346
inline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id)
347
15
{
348
15
   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
349
15
   --pmp;
350
15
   if(pmp < m_stack_base)
351
0
   {
352
0
      extend_stack();
353
0
      pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
354
0
      --pmp;
355
0
   }
356
15
   (void) new (pmp)saved_single_repeat<BidiIterator>(c, r, last_position, state_id);
357
15
   m_backup_state = pmp;
358
15
}
359
360
template <class BidiIterator, class Allocator, class traits>
361
inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2)
362
0
{
363
0
   saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
364
0
   --pmp;
365
0
   if(pmp < m_stack_base)
366
0
   {
367
0
      extend_stack();
368
0
      pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
369
0
      --pmp;
370
0
   }
371
0
   (void) new (pmp)saved_recursion<results_type>(idx, p, presults, presults2);
372
0
   m_backup_state = pmp;
373
0
}
374
375
template <class BidiIterator, class Allocator, class traits>
376
bool perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case()
377
0
{
378
   // change our case sensitivity:
379
0
   push_case_change(this->icase);
380
0
   this->icase = static_cast<const re_case*>(pstate)->icase;
381
0
   pstate = pstate->next.p;
382
0
   return true;
383
0
}
384
385
template <class BidiIterator, class Allocator, class traits>
386
bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
387
20
{
388
20
   int index = static_cast<const re_brace*>(pstate)->index;
389
20
   icase = static_cast<const re_brace*>(pstate)->icase;
390
20
   switch(index)
391
20
   {
392
5
   case 0:
393
5
      pstate = pstate->next.p;
394
5
      break;
395
0
   case -1:
396
0
   case -2:
397
0
      {
398
         // forward lookahead assert:
399
0
         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
400
0
         pstate = pstate->next.p->next.p;
401
0
         push_assertion(next_pstate, index == -1);
402
0
         break;
403
0
      }
404
0
   case -3:
405
0
      {
406
         // independent sub-expression, currently this is always recursive:
407
0
         bool old_independent = m_independent;
408
0
         m_independent = true;
409
0
         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
410
0
         pstate = pstate->next.p->next.p;
411
0
         bool r = false;
412
0
#if !defined(BOOST_NO_EXCEPTIONS)
413
0
      try{
414
0
#endif
415
0
         r = match_all_states();
416
0
         if(!r && !m_independent)
417
0
         {
418
            // Must be unwinding from a COMMIT/SKIP/PRUNE and the independent 
419
            // sub failed, need to unwind everything else:
420
0
            while(unwind(false));
421
0
            return false;
422
0
         }
423
0
#if !defined(BOOST_NO_EXCEPTIONS)
424
0
      }
425
0
      catch(...)
426
0
      {
427
0
         pstate = next_pstate;
428
         // unwind all pushed states, apart from anything else this
429
         // ensures that all the states are correctly destructed
430
         // not just the memory freed.
431
0
         while(unwind(true)) {}
432
0
         throw;
433
0
      }
434
0
#endif
435
0
      pstate = next_pstate;
436
0
      m_independent = old_independent;
437
#ifdef BOOST_REGEX_MATCH_EXTRA
438
         if(r && (m_match_flags & match_extra))
439
         {
440
            //
441
            // our captures have been stored in *m_presult
442
            // we need to unpack them, and insert them
443
            // back in the right order when we unwind the stack:
444
            //
445
            match_results<BidiIterator, Allocator> temp_match(*m_presult);
446
            unsigned i;
447
            for(i = 0; i < temp_match.size(); ++i)
448
               (*m_presult)[i].get_captures().clear();
449
            // match everything else:
450
#if !defined(BOOST_NO_EXCEPTIONS)
451
            try{
452
#endif
453
               r = match_all_states();
454
#if !defined(BOOST_NO_EXCEPTIONS)
455
            }
456
            catch(...)
457
            {
458
               pstate = next_pstate;
459
               // unwind all pushed states, apart from anything else this
460
               // ensures that all the states are correctly destructed
461
               // not just the memory freed.
462
               while(unwind(true)) {}
463
               throw;
464
            }
465
#endif
466
         // now place the stored captures back:
467
            for(i = 0; i < temp_match.size(); ++i)
468
            {
469
               typedef typename sub_match<BidiIterator>::capture_sequence_type seq;
470
               seq& s1 = (*m_presult)[i].get_captures();
471
               const seq& s2 = temp_match[i].captures();
472
               s1.insert(
473
                  s1.end(), 
474
                  s2.begin(), 
475
                  s2.end());
476
            }
477
         }
478
#endif
479
0
         return r;
480
0
      }
481
0
   case -4:
482
0
      {
483
      // conditional expression:
484
0
      const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);
485
0
      BOOST_REGEX_ASSERT(alt->type == syntax_element_alt);
486
0
      pstate = alt->next.p;
487
0
      if(pstate->type == syntax_element_assert_backref)
488
0
      {
489
0
         if(!match_assert_backref())
490
0
            pstate = alt->alt.p;
491
0
         break;
492
0
      }
493
0
      else
494
0
      {
495
         // zero width assertion, have to match this recursively:
496
0
         BOOST_REGEX_ASSERT(pstate->type == syntax_element_startmark);
497
0
         bool negated = static_cast<const re_brace*>(pstate)->index == -2;
498
0
         BidiIterator saved_position = position;
499
0
         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
500
0
         pstate = pstate->next.p->next.p;
501
0
#if !defined(BOOST_NO_EXCEPTIONS)
502
0
         try{
503
0
#endif
504
0
            bool r = match_all_states();
505
0
            position = saved_position;
506
0
            if(negated)
507
0
               r = !r;
508
0
            if(r)
509
0
               pstate = next_pstate;
510
0
            else
511
0
               pstate = alt->alt.p;
512
0
#if !defined(BOOST_NO_EXCEPTIONS)
513
0
         }
514
0
         catch(...)
515
0
         {
516
0
            pstate = next_pstate;
517
            // unwind all pushed states, apart from anything else this
518
            // ensures that all the states are correctly destructed
519
            // not just the memory freed.
520
0
            while(unwind(true)){}
521
0
            throw;
522
0
         }
523
0
#endif
524
0
         break;
525
0
      }
526
0
      }
527
0
   case -5:
528
0
      {
529
0
         push_matched_paren(0, (*m_presult)[0]);
530
0
         m_presult->set_first(position, 0, true);
531
0
         pstate = pstate->next.p;
532
0
         break;
533
0
      }
534
15
   default:
535
15
   {
536
15
      BOOST_REGEX_ASSERT(index > 0);
537
15
      if((m_match_flags & match_nosubs) == 0)
538
15
      {
539
15
         push_matched_paren(index, (*m_presult)[index]);
540
15
         m_presult->set_first(position, index);
541
15
      }
542
15
      pstate = pstate->next.p;
543
15
      break;
544
0
   }
545
20
   }
546
20
   return true;
547
20
}
548
549
template <class BidiIterator, class Allocator, class traits>
550
bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
551
0
{
552
0
   bool take_first, take_second;
553
0
   const re_alt* jmp = static_cast<const re_alt*>(pstate);
554
555
   // find out which of these two alternatives we need to take:
556
0
   if(position == last)
557
0
   {
558
0
      take_first = jmp->can_be_null & mask_take;
559
0
      take_second = jmp->can_be_null & mask_skip;
560
0
   }
561
0
   else
562
0
   {
563
0
      take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
564
0
      take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
565
0
  }
566
567
0
   if(take_first)
568
0
   {
569
      // we can take the first alternative,
570
      // see if we need to push next alternative:
571
0
      if(take_second)
572
0
      {
573
0
         push_alt(jmp->alt.p);
574
0
      }
575
0
      pstate = pstate->next.p;
576
0
      return true;
577
0
   }
578
0
   if(take_second)
579
0
   {
580
0
      pstate = jmp->alt.p;
581
0
      return true;
582
0
   }
583
0
   return false;  // neither option is possible
584
0
}
585
586
template <class BidiIterator, class Allocator, class traits>
587
bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
588
18
{
589
#ifdef BOOST_REGEX_MSVC
590
#pragma warning(push)
591
#pragma warning(disable:4127 4244)
592
#endif
593
#ifdef BOOST_BORLANDC
594
#pragma option push -w-8008 -w-8066 -w-8004
595
#endif
596
18
   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
597
598
   // find out which of these two alternatives we need to take:
599
18
   bool take_first, take_second;
600
18
   if(position == last)
601
3
   {
602
3
      take_first = rep->can_be_null & mask_take;
603
3
      take_second = rep->can_be_null & mask_skip;
604
3
   }
605
15
   else
606
15
   {
607
15
      take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
608
15
      take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
609
15
   }
610
611
18
   if((m_backup_state->state_id != saved_state_repeater_count) 
612
18
      || (static_cast<saved_repeater<BidiIterator>*>(m_backup_state)->count.get_id() != rep->state_id)
613
18
      || (next_count->get_id() != rep->state_id))
614
18
   {
615
      // we're moving to a different repeat from the last
616
      // one, so set up a counter object:
617
18
      push_repeater_count(rep->state_id, &next_count);
618
18
   }
619
   //
620
   // If we've had at least one repeat already, and the last one 
621
   // matched the NULL string then set the repeat count to
622
   // maximum:
623
   //
624
18
   next_count->check_null_repeat(position, rep->max);
625
626
18
   if(next_count->get_count() < rep->min)
627
3
   {
628
      // we must take the repeat:
629
3
      if(take_first)
630
3
      {
631
         // increase the counter:
632
3
         ++(*next_count);
633
3
         pstate = rep->next.p;
634
3
         return true;
635
3
      }
636
0
      return false;
637
3
   }
638
639
15
   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
640
15
   if(greedy)
641
0
   {
642
      // try and take the repeat if we can:
643
0
      if((next_count->get_count() < rep->max) && take_first)
644
0
      {
645
0
         if(take_second)
646
0
         {
647
            // store position in case we fail:
648
0
            push_alt(rep->alt.p);
649
0
         }
650
         // increase the counter:
651
0
         ++(*next_count);
652
0
         pstate = rep->next.p;
653
0
         return true;
654
0
      }
655
0
      else if(take_second)
656
0
      {
657
0
         pstate = rep->alt.p;
658
0
         return true;
659
0
      }
660
0
      return false; // can't take anything, fail...
661
0
   }
662
15
   else // non-greedy
663
15
   {
664
      // try and skip the repeat if we can:
665
15
      if(take_second)
666
3
      {
667
3
         if((next_count->get_count() < rep->max) && take_first)
668
0
         {
669
            // store position in case we fail:
670
0
            push_non_greedy_repeat(rep->next.p);
671
0
         }
672
3
         pstate = rep->alt.p;
673
3
         return true;
674
3
      }
675
12
      if((next_count->get_count() < rep->max) && take_first)
676
12
      {
677
         // increase the counter:
678
12
         ++(*next_count);
679
12
         pstate = rep->next.p;
680
12
         return true;
681
12
      }
682
12
   }
683
0
   return false;
684
#ifdef BOOST_BORLANDC
685
#pragma option pop
686
#endif
687
#ifdef BOOST_REGEX_MSVC
688
#pragma warning(pop)
689
#endif
690
15
}
691
692
template <class BidiIterator, class Allocator, class traits>
693
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
694
0
{
695
0
   std::size_t count = 0;
696
0
   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
697
0
   re_syntax_base* psingle = rep->next.p;
698
   // match compulsory repeats first:
699
0
   while(count < rep->min)
700
0
   {
701
0
      pstate = psingle;
702
0
      if(!match_wild())
703
0
         return false;
704
0
      ++count;
705
0
   }
706
0
   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
707
0
   if(greedy)
708
0
   {
709
      // repeat for as long as we can:
710
0
      while(count < rep->max)
711
0
      {
712
0
         pstate = psingle;
713
0
         if(!match_wild())
714
0
            break;
715
0
         ++count;
716
0
      }
717
      // remember where we got to if this is a leading repeat:
718
0
      if((rep->leading) && (count < rep->max))
719
0
         restart = position;
720
      // push backtrack info if available:
721
0
      if(count - rep->min)
722
0
         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
723
      // jump to next state:
724
0
      pstate = rep->alt.p;
725
0
      return true;
726
0
   }
727
0
   else
728
0
   {
729
      // non-greedy, push state and return true if we can skip:
730
0
      if(count < rep->max)
731
0
         push_single_repeat(count, rep, position, saved_state_rep_slow_dot);
732
0
      pstate = rep->alt.p;
733
0
      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
734
0
   }
735
0
}
736
737
template <class BidiIterator, class Allocator, class traits>
738
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
739
0
{
740
0
   if(m_match_flags & match_not_dot_null)
741
0
      return match_dot_repeat_slow();
742
0
   if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
743
0
      return match_dot_repeat_slow();
744
745
0
   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
746
0
   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
747
0
   std::size_t count = static_cast<std::size_t>((std::min)(static_cast<std::size_t>(std::distance(position, last)), greedy ? rep->max : rep->min));
748
0
   if(rep->min > count)
749
0
   {
750
0
      position = last;
751
0
      return false;  // not enough text left to match
752
0
   }
753
0
   std::advance(position, count);
754
755
0
   if(greedy)
756
0
   {
757
0
      if((rep->leading) && (count < rep->max))
758
0
         restart = position;
759
      // push backtrack info if available:
760
0
      if(count - rep->min)
761
0
         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
762
      // jump to next state:
763
0
      pstate = rep->alt.p;
764
0
      return true;
765
0
   }
766
0
   else
767
0
   {
768
      // non-greedy, push state and return true if we can skip:
769
0
      if(count < rep->max)
770
0
         push_single_repeat(count, rep, position, saved_state_rep_fast_dot);
771
0
      pstate = rep->alt.p;
772
0
      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
773
0
   }
774
0
}
775
776
template <class BidiIterator, class Allocator, class traits>
777
bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
778
0
{
779
#ifdef BOOST_REGEX_MSVC
780
#pragma warning(push)
781
#pragma warning(disable:4127)
782
#endif
783
#ifdef BOOST_BORLANDC
784
#pragma option push -w-8008 -w-8066 -w-8004
785
#endif
786
0
   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
787
0
   BOOST_REGEX_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);
788
0
   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);
789
0
   std::size_t count = 0;
790
   //
791
   // start by working out how much we can skip:
792
   //
793
0
   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
794
0
   std::size_t desired = greedy ? rep->max : rep->min;
795
0
   if(::boost::is_random_access_iterator<BidiIterator>::value)
796
0
   {
797
0
      BidiIterator end = position;
798
      // Move end forward by "desired", preferably without using distance or advance if we can
799
      // as these can be slow for some iterator types.
800
0
      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : std::distance(position, last);
801
0
      if(desired >= len)
802
0
         end = last;
803
0
      else
804
0
         std::advance(end, desired);
805
0
      BidiIterator origin(position);
806
0
      while((position != end) && (traits_inst.translate(*position, icase) == what))
807
0
      {
808
0
         ++position;
809
0
      }
810
0
      count = (unsigned)std::distance(origin, position);
811
0
   }
812
0
   else
813
0
   {
814
0
      while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))
815
0
      {
816
0
         ++position;
817
0
         ++count;
818
0
      }
819
0
   }
820
821
0
   if(count < rep->min)
822
0
      return false;
823
824
0
   if(greedy)
825
0
   {
826
0
      if((rep->leading) && (count < rep->max))
827
0
         restart = position;
828
      // push backtrack info if available:
829
0
      if(count - rep->min)
830
0
         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
831
      // jump to next state:
832
0
      pstate = rep->alt.p;
833
0
      return true;
834
0
   }
835
0
   else
836
0
   {
837
      // non-greedy, push state and return true if we can skip:
838
0
      if(count < rep->max)
839
0
         push_single_repeat(count, rep, position, saved_state_rep_char);
840
0
      pstate = rep->alt.p;
841
0
      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
842
0
   }
843
#ifdef BOOST_BORLANDC
844
#pragma option pop
845
#endif
846
#ifdef BOOST_REGEX_MSVC
847
#pragma warning(pop)
848
#endif
849
0
}
850
851
template <class BidiIterator, class Allocator, class traits>
852
bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
853
15
{
854
#ifdef BOOST_REGEX_MSVC
855
#pragma warning(push)
856
#pragma warning(disable:4127)
857
#endif
858
#ifdef BOOST_BORLANDC
859
#pragma option push -w-8008 -w-8066 -w-8004
860
#endif
861
15
   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
862
15
   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
863
15
   std::size_t count = 0;
864
   //
865
   // start by working out how much we can skip:
866
   //
867
15
   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
868
15
   std::size_t desired = greedy ? rep->max : rep->min;
869
15
   if(::boost::is_random_access_iterator<BidiIterator>::value)
870
15
   {
871
15
      BidiIterator end = position;
872
      // Move end forward by "desired", preferably without using distance or advance if we can
873
      // as these can be slow for some iterator types.
874
15
      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : std::distance(position, last);
875
15
      if(desired >= len)
876
0
         end = last;
877
15
      else
878
15
         std::advance(end, desired);
879
15
      BidiIterator origin(position);
880
30
      while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
881
15
      {
882
15
         ++position;
883
15
      }
884
15
      count = (unsigned)std::distance(origin, position);
885
15
   }
886
0
   else
887
0
   {
888
0
      while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
889
0
      {
890
0
         ++position;
891
0
         ++count;
892
0
      }
893
0
   }
894
895
15
   if(count < rep->min)
896
0
      return false;
897
898
15
   if(greedy)
899
0
   {
900
0
      if((rep->leading) && (count < rep->max))
901
0
         restart = position;
902
      // push backtrack info if available:
903
0
      if(count - rep->min)
904
0
         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
905
      // jump to next state:
906
0
      pstate = rep->alt.p;
907
0
      return true;
908
0
   }
909
15
   else
910
15
   {
911
      // non-greedy, push state and return true if we can skip:
912
15
      if(count < rep->max)
913
15
         push_single_repeat(count, rep, position, saved_state_rep_short_set);
914
15
      pstate = rep->alt.p;
915
15
      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
916
15
   }
917
#ifdef BOOST_BORLANDC
918
#pragma option pop
919
#endif
920
#ifdef BOOST_REGEX_MSVC
921
#pragma warning(pop)
922
#endif
923
15
}
924
925
template <class BidiIterator, class Allocator, class traits>
926
bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
927
0
{
928
#ifdef BOOST_REGEX_MSVC
929
#pragma warning(push)
930
#pragma warning(disable:4127)
931
#endif
932
#ifdef BOOST_BORLANDC
933
#pragma option push -w-8008 -w-8066 -w-8004
934
#endif
935
0
   typedef typename traits::char_class_type m_type;
936
0
   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
937
0
   const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate->next.p);
938
0
   std::size_t count = 0;
939
   //
940
   // start by working out how much we can skip:
941
   //
942
0
   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
943
0
   std::size_t desired = greedy ? rep->max : rep->min;
944
0
   if(::boost::is_random_access_iterator<BidiIterator>::value)
945
0
   {
946
0
      BidiIterator end = position;
947
      // Move end forward by "desired", preferably without using distance or advance if we can
948
      // as these can be slow for some iterator types.
949
0
      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : std::distance(position, last);
950
0
      if(desired >= len)
951
0
         end = last;
952
0
      else
953
0
         std::advance(end, desired);
954
0
      BidiIterator origin(position);
955
0
      while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
956
0
      {
957
0
         ++position;
958
0
      }
959
0
      count = (unsigned)std::distance(origin, position);
960
0
   }
961
0
   else
962
0
   {
963
0
      while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
964
0
      {
965
0
         ++position;
966
0
         ++count;
967
0
      }
968
0
   }
969
970
0
   if(count < rep->min)
971
0
      return false;
972
973
0
   if(greedy)
974
0
   {
975
0
      if((rep->leading) && (count < rep->max))
976
0
         restart = position;
977
      // push backtrack info if available:
978
0
      if(count - rep->min)
979
0
         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
980
      // jump to next state:
981
0
      pstate = rep->alt.p;
982
0
      return true;
983
0
   }
984
0
   else
985
0
   {
986
      // non-greedy, push state and return true if we can skip:
987
0
      if(count < rep->max)
988
0
         push_single_repeat(count, rep, position, saved_state_rep_long_set);
989
0
      pstate = rep->alt.p;
990
0
      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
991
0
   }
992
#ifdef BOOST_BORLANDC
993
#pragma option pop
994
#endif
995
#ifdef BOOST_REGEX_MSVC
996
#pragma warning(pop)
997
#endif
998
0
}
999
1000
template <class BidiIterator, class Allocator, class traits>
1001
bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
1002
0
{
1003
0
   BOOST_REGEX_ASSERT(pstate->type == syntax_element_recurse);
1004
   //
1005
   // See if we've seen this recursion before at this location, if we have then
1006
   // we need to prevent infinite recursion:
1007
   //
1008
0
   for(typename std::vector<recursion_info<results_type> >::reverse_iterator i = recursion_stack.rbegin(); i != recursion_stack.rend(); ++i)
1009
0
   {
1010
0
      if(i->idx == static_cast<const re_brace*>(static_cast<const re_jump*>(pstate)->alt.p)->index)
1011
0
      {
1012
0
         if(i->location_of_start == position)
1013
0
            return false;
1014
0
         break;
1015
0
      }
1016
0
   }
1017
   //
1018
   // Backup call stack:
1019
   //
1020
0
   push_recursion_pop();
1021
   //
1022
   // Set new call stack:
1023
   //
1024
0
   if(recursion_stack.capacity() == 0)
1025
0
   {
1026
0
      recursion_stack.reserve(50);
1027
0
   }
1028
0
   recursion_stack.push_back(recursion_info<results_type>());
1029
0
   recursion_stack.back().preturn_address = pstate->next.p;
1030
0
   recursion_stack.back().results = *m_presult;
1031
0
   pstate = static_cast<const re_jump*>(pstate)->alt.p;
1032
0
   recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;
1033
0
   recursion_stack.back().location_of_start = position;
1034
   //if(static_cast<const re_recurse*>(pstate)->state_id > 0)
1035
0
   {
1036
0
      push_repeater_count(-(2 + static_cast<const re_brace*>(pstate)->index), &next_count);
1037
0
   }
1038
1039
0
   return true;
1040
0
}
1041
1042
template <class BidiIterator, class Allocator, class traits>
1043
bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
1044
15
{
1045
15
   int index = static_cast<const re_brace*>(pstate)->index;
1046
15
   icase = static_cast<const re_brace*>(pstate)->icase;
1047
15
   if(index > 0)
1048
15
   {
1049
15
      if((m_match_flags & match_nosubs) == 0)
1050
15
      {
1051
15
         m_presult->set_second(position, index);
1052
15
      }
1053
15
      if(!recursion_stack.empty())
1054
0
      {
1055
0
         if(index == recursion_stack.back().idx)
1056
0
         {
1057
0
            pstate = recursion_stack.back().preturn_address;
1058
0
            *m_presult = recursion_stack.back().results;
1059
0
            push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);
1060
0
            recursion_stack.pop_back();
1061
0
            push_repeater_count(-(2 + index), &next_count);
1062
0
         }
1063
0
      }
1064
15
   }
1065
0
   else if((index < 0) && (index != -4))
1066
0
   {
1067
      // matched forward lookahead:
1068
0
      pstate = 0;
1069
0
      return true;
1070
0
   }
1071
15
   pstate = pstate->next.p;
1072
15
   return true;
1073
15
}
1074
1075
template <class BidiIterator, class Allocator, class traits>
1076
bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
1077
3
{
1078
3
   if(!recursion_stack.empty())
1079
0
   {
1080
0
      BOOST_REGEX_ASSERT(0 == recursion_stack.back().idx);
1081
0
      pstate = recursion_stack.back().preturn_address;
1082
0
      push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);
1083
0
      *m_presult = recursion_stack.back().results;
1084
0
      recursion_stack.pop_back();
1085
0
      return true;
1086
0
   }
1087
3
   if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
1088
0
      return false;
1089
3
   if((m_match_flags & match_all) && (position != last))
1090
0
      return false;
1091
3
   if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))
1092
0
      return false;
1093
3
   m_presult->set_second(position);
1094
3
   pstate = 0;
1095
3
   m_has_found_match = true;
1096
3
   if((m_match_flags & match_posix) == match_posix)
1097
0
   {
1098
0
      m_result.maybe_assign(*m_presult);
1099
0
      if((m_match_flags & match_any) == 0)
1100
0
         return false;
1101
0
   }
1102
#ifdef BOOST_REGEX_MATCH_EXTRA
1103
   if(match_extra & m_match_flags)
1104
   {
1105
      for(unsigned i = 0; i < m_presult->size(); ++i)
1106
         if((*m_presult)[i].matched)
1107
            ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);
1108
   }
1109
#endif
1110
3
   return true;
1111
3
}
1112
1113
template <class BidiIterator, class Allocator, class traits>
1114
bool perl_matcher<BidiIterator, Allocator, traits>::match_commit()
1115
0
{
1116
   // Ideally we would just junk all the states that are on the stack,
1117
   // however we might not unwind correctly in that case, so for now,
1118
   // just mark that we don't backtrack into whatever is left (or rather
1119
   // we'll unwind it unconditionally without pausing to try other matches).
1120
1121
0
   switch(static_cast<const re_commit*>(pstate)->action)
1122
0
   {
1123
0
   case commit_commit:
1124
0
      restart = last;
1125
0
      break;
1126
0
   case commit_skip:
1127
0
      if(base != position)
1128
0
      {
1129
0
         restart = position;
1130
         // Have to decrement restart since it will get incremented again later:
1131
0
         --restart;
1132
0
      }
1133
0
      break;
1134
0
   case commit_prune:
1135
0
      break;
1136
0
   }
1137
1138
0
   saved_state* pmp = m_backup_state;
1139
0
   --pmp;
1140
0
   if(pmp < m_stack_base)
1141
0
   {
1142
0
      extend_stack();
1143
0
      pmp = m_backup_state;
1144
0
      --pmp;
1145
0
   }
1146
0
   (void) new (pmp)saved_state(16);
1147
0
   m_backup_state = pmp;
1148
0
   pstate = pstate->next.p;
1149
0
   return true;
1150
0
}
1151
1152
template <class BidiIterator, class Allocator, class traits>
1153
bool perl_matcher<BidiIterator, Allocator, traits>::match_then()
1154
0
{
1155
   // Just leave a mark that we need to skip to next alternative:
1156
0
   saved_state* pmp = m_backup_state;
1157
0
   --pmp;
1158
0
   if(pmp < m_stack_base)
1159
0
   {
1160
0
      extend_stack();
1161
0
      pmp = m_backup_state;
1162
0
      --pmp;
1163
0
   }
1164
0
   (void) new (pmp)saved_state(17);
1165
0
   m_backup_state = pmp;
1166
0
   pstate = pstate->next.p;
1167
0
   return true;
1168
0
}
1169
1170
template <class BidiIterator, class Allocator, class traits>
1171
bool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool have_match)
1172
0
{
1173
0
   while(pstate)
1174
0
   {
1175
0
      if(pstate->type == syntax_element_endmark)
1176
0
      {
1177
0
         if(static_cast<const re_brace*>(pstate)->index == index)
1178
0
         {
1179
0
            if(have_match)
1180
0
               return this->match_endmark();
1181
0
            pstate = pstate->next.p;
1182
0
            return true;
1183
0
         }
1184
0
         else
1185
0
         {
1186
            // Unenclosed closing ), occurs when (*ACCEPT) is inside some other 
1187
            // parenthesis which may or may not have other side effects associated with it.
1188
0
            const re_syntax_base* sp = pstate;
1189
0
            match_endmark();
1190
0
            if(!pstate)
1191
0
            {
1192
0
               unwind(true);
1193
               // unwind may leave pstate NULL if we've unwound a forward lookahead, in which
1194
               // case just move to the next state and keep looking...
1195
0
               if (!pstate)
1196
0
                  pstate = sp->next.p;
1197
0
            }
1198
0
         }
1199
0
         continue;
1200
0
      }
1201
0
      else if(pstate->type == syntax_element_match)
1202
0
         return true;
1203
0
      else if(pstate->type == syntax_element_startmark)
1204
0
      {
1205
0
         int idx = static_cast<const re_brace*>(pstate)->index;
1206
0
         pstate = pstate->next.p;
1207
0
         skip_until_paren(idx, false);
1208
0
         continue;
1209
0
      }
1210
0
      pstate = pstate->next.p;
1211
0
   }
1212
0
   return true;
1213
0
}
1214
1215
/****************************************************************************
1216
1217
Unwind and associated procedures follow, these perform what normal stack
1218
unwinding does in the recursive implementation.
1219
1220
****************************************************************************/
1221
1222
template <class BidiIterator, class Allocator, class traits>
1223
bool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)
1224
11
{
1225
11
   static unwind_proc_type const s_unwind_table[19] = 
1226
11
   {
1227
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_end,
1228
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_paren,
1229
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper,
1230
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion,
1231
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_alt,
1232
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter,
1233
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block,
1234
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat,
1235
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat,
1236
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat,
1237
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat,
1238
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat,
1239
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat,
1240
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat,
1241
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion,
1242
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop,
1243
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_commit,
1244
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_then,
1245
11
      &perl_matcher<BidiIterator, Allocator, traits>::unwind_case,
1246
11
   };
1247
1248
11
   m_recursive_result = have_match;
1249
11
   m_unwound_lookahead = false;
1250
11
   m_unwound_alt = false;
1251
11
   unwind_proc_type unwinder;
1252
11
   bool cont;
1253
   //
1254
   // keep unwinding our stack until we have something to do:
1255
   //
1256
11
   do
1257
59
   {
1258
59
      unwinder = s_unwind_table[m_backup_state->state_id];
1259
59
      cont = (this->*unwinder)(m_recursive_result);
1260
59
   }while(cont);
1261
   //
1262
   // return true if we have more states to try:
1263
   //
1264
11
   return pstate ? true : false;
1265
11
}
1266
1267
template <class BidiIterator, class Allocator, class traits>
1268
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_end(bool)
1269
0
{
1270
0
   pstate = 0;   // nothing left to search
1271
0
   return false; // end of stack nothing more to search
1272
0
}
1273
1274
template <class BidiIterator, class Allocator, class traits>
1275
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_case(bool)
1276
0
{
1277
0
   saved_change_case* pmp = static_cast<saved_change_case*>(m_backup_state);
1278
0
   icase = pmp->icase;
1279
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
1280
0
   m_backup_state = pmp;
1281
0
   return true;
1282
0
}
1283
1284
template <class BidiIterator, class Allocator, class traits>
1285
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match)
1286
15
{
1287
15
   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
1288
   // restore previous values if no match was found:
1289
15
   if(!have_match)
1290
0
   {
1291
0
      m_presult->set_first(pmp->sub.first, pmp->index, pmp->index == 0);
1292
0
      m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched, pmp->index == 0);
1293
0
   }
1294
#ifdef BOOST_REGEX_MATCH_EXTRA
1295
   //
1296
   // we have a match, push the capture information onto the stack:
1297
   //
1298
   else if(pmp->sub.matched && (match_extra & m_match_flags))
1299
      ((*m_presult)[pmp->index]).get_captures().push_back(pmp->sub);
1300
#endif
1301
   // unwind stack:
1302
15
   m_backup_state = pmp+1;
1303
15
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp);
1304
15
   return true; // keep looking
1305
15
}
1306
1307
template <class BidiIterator, class Allocator, class traits>
1308
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper(bool)
1309
5
{
1310
5
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);
1311
5
   pstate = 0;   // nothing left to search
1312
5
   return false; // end of stack nothing more to search
1313
5
}
1314
1315
template <class BidiIterator, class Allocator, class traits>
1316
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion(bool r)
1317
0
{
1318
0
   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
1319
0
   pstate = pmp->pstate;
1320
0
   position = pmp->position;
1321
0
   bool result = (r == pmp->positive);
1322
0
   m_recursive_result = pmp->positive ? r : !r;
1323
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
1324
0
   m_backup_state = pmp;
1325
0
   m_unwound_lookahead = true;
1326
0
   return !result; // return false if the assertion was matched to stop search.
1327
0
}
1328
1329
template <class BidiIterator, class Allocator, class traits>
1330
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_alt(bool r)
1331
0
{
1332
0
   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
1333
0
   if(!r)
1334
0
   {
1335
0
      pstate = pmp->pstate;
1336
0
      position = pmp->position;
1337
0
   }
1338
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
1339
0
   m_backup_state = pmp;
1340
0
   m_unwound_alt = !r;
1341
0
   return r; 
1342
0
}
1343
1344
template <class BidiIterator, class Allocator, class traits>
1345
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter(bool)
1346
18
{
1347
18
   saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
1348
18
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
1349
18
   m_backup_state = pmp;
1350
18
   return true; // keep looking
1351
18
}
1352
1353
template <class BidiIterator, class Allocator, class traits>
1354
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block(bool)
1355
0
{
1356
0
   saved_extra_block* pmp = static_cast<saved_extra_block*>(m_backup_state);
1357
0
   void* condemmed = m_stack_base;
1358
0
   m_stack_base = pmp->base;
1359
0
   m_backup_state = pmp->end;
1360
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp);
1361
0
   put_mem_block(condemmed);
1362
0
   return true; // keep looking
1363
0
}
1364
1365
template <class BidiIterator, class Allocator, class traits>
1366
inline void perl_matcher<BidiIterator, Allocator, traits>::destroy_single_repeat()
1367
15
{
1368
15
   saved_single_repeat<BidiIterator>* p = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
1369
15
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(p++);
1370
15
   m_backup_state = p;
1371
15
}
1372
1373
template <class BidiIterator, class Allocator, class traits>
1374
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat(bool r)
1375
0
{
1376
0
   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
1377
1378
   // if we have a match, just discard this state:
1379
0
   if(r) 
1380
0
   {
1381
0
      destroy_single_repeat();
1382
0
      return true;
1383
0
   }
1384
1385
0
   const re_repeat* rep = pmp->rep;
1386
0
   std::size_t count = pmp->count;
1387
0
   BOOST_REGEX_ASSERT(rep->next.p != 0);
1388
0
   BOOST_REGEX_ASSERT(rep->alt.p != 0);
1389
1390
0
   count -= rep->min;
1391
   
1392
0
   if((m_match_flags & match_partial) && (position == last))
1393
0
      m_has_partial_match = true;
1394
1395
0
   BOOST_REGEX_ASSERT(count);
1396
0
   position = pmp->last_position;
1397
1398
   // backtrack till we can skip out:
1399
0
   do
1400
0
   {
1401
0
      --position;
1402
0
      --count;
1403
0
      ++state_count;
1404
0
   }while(count && !can_start(*position, rep->_map, mask_skip));
1405
1406
   // if we've hit base, destroy this state:
1407
0
   if(count == 0)
1408
0
   {
1409
0
         destroy_single_repeat();
1410
0
         if(!can_start(*position, rep->_map, mask_skip))
1411
0
            return true;
1412
0
   }
1413
0
   else
1414
0
   {
1415
0
      pmp->count = count + rep->min;
1416
0
      pmp->last_position = position;
1417
0
   }
1418
0
   pstate = rep->alt.p;
1419
0
   return false;
1420
0
}
1421
1422
template <class BidiIterator, class Allocator, class traits>
1423
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat(bool r)
1424
0
{
1425
0
   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
1426
1427
   // if we have a match, just discard this state:
1428
0
   if(r) 
1429
0
   {
1430
0
      destroy_single_repeat();
1431
0
      return true;
1432
0
   }
1433
1434
0
   const re_repeat* rep = pmp->rep;
1435
0
   std::size_t count = pmp->count;
1436
0
   BOOST_REGEX_ASSERT(rep->type == syntax_element_dot_rep);
1437
0
   BOOST_REGEX_ASSERT(rep->next.p != 0);
1438
0
   BOOST_REGEX_ASSERT(rep->alt.p != 0);
1439
0
   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_wild);
1440
1441
0
   BOOST_REGEX_ASSERT(count < rep->max);
1442
0
   pstate = rep->next.p;
1443
0
   position = pmp->last_position;
1444
1445
0
   if(position != last)
1446
0
   {
1447
      // wind forward until we can skip out of the repeat:
1448
0
      do
1449
0
      {
1450
0
         if(!match_wild())
1451
0
         {
1452
            // failed repeat match, discard this state and look for another:
1453
0
            destroy_single_repeat();
1454
0
            return true;
1455
0
         }
1456
0
         ++count;
1457
0
         ++state_count;
1458
0
         pstate = rep->next.p;
1459
0
      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
1460
0
   }   
1461
0
   if(position == last)
1462
0
   {
1463
      // can't repeat any more, remove the pushed state: 
1464
0
      destroy_single_repeat();
1465
0
      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
1466
0
         m_has_partial_match = true;
1467
0
      if(0 == (rep->can_be_null & mask_skip))
1468
0
         return true;
1469
0
   }
1470
0
   else if(count == rep->max)
1471
0
   {
1472
      // can't repeat any more, remove the pushed state: 
1473
0
      destroy_single_repeat();
1474
0
      if(!can_start(*position, rep->_map, mask_skip))
1475
0
         return true;
1476
0
   }
1477
0
   else
1478
0
   {
1479
0
      pmp->count = count;
1480
0
      pmp->last_position = position;
1481
0
   }
1482
0
   pstate = rep->alt.p;
1483
0
   return false;
1484
0
}
1485
1486
template <class BidiIterator, class Allocator, class traits>
1487
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat(bool r)
1488
0
{
1489
0
   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
1490
1491
   // if we have a match, just discard this state:
1492
0
   if(r) 
1493
0
   {
1494
0
      destroy_single_repeat();
1495
0
      return true;
1496
0
   }
1497
1498
0
   const re_repeat* rep = pmp->rep;
1499
0
   std::size_t count = pmp->count;
1500
1501
0
   BOOST_REGEX_ASSERT(count < rep->max);
1502
0
   position = pmp->last_position;
1503
0
   if(position != last)
1504
0
   {
1505
1506
      // wind forward until we can skip out of the repeat:
1507
0
      do
1508
0
      {
1509
0
         ++position;
1510
0
         ++count;
1511
0
         ++state_count;
1512
0
      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
1513
0
   }
1514
1515
   // remember where we got to if this is a leading repeat:
1516
0
   if((rep->leading) && (count < rep->max))
1517
0
      restart = position;
1518
0
   if(position == last)
1519
0
   {
1520
      // can't repeat any more, remove the pushed state: 
1521
0
      destroy_single_repeat();
1522
0
      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
1523
0
         m_has_partial_match = true;
1524
0
      if(0 == (rep->can_be_null & mask_skip))
1525
0
         return true;
1526
0
   }
1527
0
   else if(count == rep->max)
1528
0
   {
1529
      // can't repeat any more, remove the pushed state: 
1530
0
      destroy_single_repeat();
1531
0
      if(!can_start(*position, rep->_map, mask_skip))
1532
0
         return true;
1533
0
   }
1534
0
   else
1535
0
   {
1536
0
      pmp->count = count;
1537
0
      pmp->last_position = position;
1538
0
   }
1539
0
   pstate = rep->alt.p;
1540
0
   return false;
1541
0
}
1542
1543
template <class BidiIterator, class Allocator, class traits>
1544
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat(bool r)
1545
0
{
1546
0
   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
1547
1548
   // if we have a match, just discard this state:
1549
0
   if(r) 
1550
0
   {
1551
0
      destroy_single_repeat();
1552
0
      return true;
1553
0
   }
1554
1555
0
   const re_repeat* rep = pmp->rep;
1556
0
   std::size_t count = pmp->count;
1557
0
   pstate = rep->next.p;
1558
0
   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
1559
0
   position = pmp->last_position;
1560
1561
0
   BOOST_REGEX_ASSERT(rep->type == syntax_element_char_rep);
1562
0
   BOOST_REGEX_ASSERT(rep->next.p != 0);
1563
0
   BOOST_REGEX_ASSERT(rep->alt.p != 0);
1564
0
   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_literal);
1565
0
   BOOST_REGEX_ASSERT(count < rep->max);
1566
1567
0
   if(position != last)
1568
0
   {
1569
      // wind forward until we can skip out of the repeat:
1570
0
      do
1571
0
      {
1572
0
         if(traits_inst.translate(*position, icase) != what)
1573
0
         {
1574
            // failed repeat match, discard this state and look for another:
1575
0
            destroy_single_repeat();
1576
0
            return true;
1577
0
         }
1578
0
         ++count;
1579
0
         ++ position;
1580
0
         ++state_count;
1581
0
         pstate = rep->next.p;
1582
0
      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
1583
0
   }   
1584
   // remember where we got to if this is a leading repeat:
1585
0
   if((rep->leading) && (count < rep->max))
1586
0
      restart = position;
1587
0
   if(position == last)
1588
0
   {
1589
      // can't repeat any more, remove the pushed state: 
1590
0
      destroy_single_repeat();
1591
0
      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
1592
0
         m_has_partial_match = true;
1593
0
      if(0 == (rep->can_be_null & mask_skip))
1594
0
         return true;
1595
0
   }
1596
0
   else if(count == rep->max)
1597
0
   {
1598
      // can't repeat any more, remove the pushed state: 
1599
0
      destroy_single_repeat();
1600
0
      if(!can_start(*position, rep->_map, mask_skip))
1601
0
         return true;
1602
0
   }
1603
0
   else
1604
0
   {
1605
0
      pmp->count = count;
1606
0
      pmp->last_position = position;
1607
0
   }
1608
0
   pstate = rep->alt.p;
1609
0
   return false;
1610
0
}
1611
1612
template <class BidiIterator, class Allocator, class traits>
1613
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat(bool r)
1614
21
{
1615
21
   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
1616
1617
   // if we have a match, just discard this state:
1618
21
   if(r) 
1619
15
   {
1620
15
      destroy_single_repeat();
1621
15
      return true;
1622
15
   }
1623
1624
6
   const re_repeat* rep = pmp->rep;
1625
6
   std::size_t count = pmp->count;
1626
6
   pstate = rep->next.p;
1627
6
   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
1628
6
   position = pmp->last_position;
1629
1630
6
   BOOST_REGEX_ASSERT(rep->type == syntax_element_short_set_rep);
1631
6
   BOOST_REGEX_ASSERT(rep->next.p != 0);
1632
6
   BOOST_REGEX_ASSERT(rep->alt.p != 0);
1633
6
   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_set);
1634
6
   BOOST_REGEX_ASSERT(count < rep->max);
1635
   
1636
6
   if(position != last)
1637
6
   {
1638
      // wind forward until we can skip out of the repeat:
1639
6
      do
1640
9
      {
1641
9
         if(!map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
1642
0
         {
1643
            // failed repeat match, discard this state and look for another:
1644
0
            destroy_single_repeat();
1645
0
            return true;
1646
0
         }
1647
9
         ++count;
1648
9
         ++ position;
1649
9
         ++state_count;
1650
9
         pstate = rep->next.p;
1651
9
      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
1652
6
   }   
1653
   // remember where we got to if this is a leading repeat:
1654
6
   if((rep->leading) && (count < rep->max))
1655
0
      restart = position;
1656
6
   if(position == last)
1657
0
   {
1658
      // can't repeat any more, remove the pushed state: 
1659
0
      destroy_single_repeat();
1660
0
      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
1661
0
         m_has_partial_match = true;
1662
0
      if(0 == (rep->can_be_null & mask_skip))
1663
0
         return true;
1664
0
   }
1665
6
   else if(count == rep->max)
1666
0
   {
1667
      // can't repeat any more, remove the pushed state: 
1668
0
      destroy_single_repeat();
1669
0
      if(!can_start(*position, rep->_map, mask_skip))
1670
0
         return true;
1671
0
   }
1672
6
   else
1673
6
   {
1674
6
      pmp->count = count;
1675
6
      pmp->last_position = position;
1676
6
   }
1677
6
   pstate = rep->alt.p;
1678
6
   return false;
1679
6
}
1680
1681
template <class BidiIterator, class Allocator, class traits>
1682
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat(bool r)
1683
0
{
1684
0
   typedef typename traits::char_class_type m_type;
1685
0
   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
1686
1687
   // if we have a match, just discard this state:
1688
0
   if(r)
1689
0
   {
1690
0
      destroy_single_repeat();
1691
0
      return true;
1692
0
   }
1693
1694
0
   const re_repeat* rep = pmp->rep;
1695
0
   std::size_t count = pmp->count;
1696
0
   pstate = rep->next.p;
1697
0
   const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate);
1698
0
   position = pmp->last_position;
1699
1700
0
   BOOST_REGEX_ASSERT(rep->type == syntax_element_long_set_rep);
1701
0
   BOOST_REGEX_ASSERT(rep->next.p != 0);
1702
0
   BOOST_REGEX_ASSERT(rep->alt.p != 0);
1703
0
   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_long_set);
1704
0
   BOOST_REGEX_ASSERT(count < rep->max);
1705
1706
0
   if(position != last)
1707
0
   {
1708
      // wind forward until we can skip out of the repeat:
1709
0
      do
1710
0
      {
1711
0
         if(position == re_is_set_member(position, last, set, re.get_data(), icase))
1712
0
         {
1713
            // failed repeat match, discard this state and look for another:
1714
0
            destroy_single_repeat();
1715
0
            return true;
1716
0
         }
1717
0
         ++position;
1718
0
         ++count;
1719
0
         ++state_count;
1720
0
         pstate = rep->next.p;
1721
0
      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
1722
0
   }   
1723
   // remember where we got to if this is a leading repeat:
1724
0
   if((rep->leading) && (count < rep->max))
1725
0
      restart = position;
1726
0
   if(position == last)
1727
0
   {
1728
      // can't repeat any more, remove the pushed state:
1729
0
      destroy_single_repeat();
1730
0
      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
1731
0
         m_has_partial_match = true;
1732
0
      if(0 == (rep->can_be_null & mask_skip))
1733
0
         return true;
1734
0
   }
1735
0
   else if(count == rep->max)
1736
0
   {
1737
      // can't repeat any more, remove the pushed state: 
1738
0
      destroy_single_repeat();
1739
0
      if(!can_start(*position, rep->_map, mask_skip))
1740
0
         return true;
1741
0
   }
1742
0
   else
1743
0
   {
1744
0
      pmp->count = count;
1745
0
      pmp->last_position = position;
1746
0
   }
1747
0
   pstate = rep->alt.p;
1748
0
   return false;
1749
0
}
1750
1751
template <class BidiIterator, class Allocator, class traits>
1752
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat(bool r)
1753
0
{
1754
0
   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
1755
0
   if(!r)
1756
0
   {
1757
0
      position = pmp->position;
1758
0
      pstate = pmp->pstate;
1759
0
      ++(*next_count);
1760
0
   }
1761
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
1762
0
   m_backup_state = pmp;
1763
0
   return r;
1764
0
}
1765
1766
template <class BidiIterator, class Allocator, class traits>
1767
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r)
1768
0
{
1769
   // We are backtracking back inside a recursion, need to push the info
1770
   // back onto the recursion stack, and do so unconditionally, otherwise
1771
   // we can get mismatched pushes and pops...
1772
0
   saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
1773
0
   if (!r)
1774
0
   {
1775
0
      recursion_stack.push_back(recursion_info<results_type>());
1776
0
      recursion_stack.back().idx = pmp->recursion_id;
1777
0
      recursion_stack.back().preturn_address = pmp->preturn_address;
1778
0
      recursion_stack.back().results = pmp->prior_results;
1779
0
      recursion_stack.back().location_of_start = position;
1780
0
      *m_presult = pmp->internal_results;
1781
0
   }
1782
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
1783
0
   m_backup_state = pmp;
1784
0
   return true;
1785
0
}
1786
1787
template <class BidiIterator, class Allocator, class traits>
1788
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r)
1789
0
{
1790
   // Backtracking out of a recursion, we must pop state off the recursion
1791
   // stack unconditionally to ensure matched pushes and pops:
1792
0
   saved_state* pmp = static_cast<saved_state*>(m_backup_state);
1793
0
   if (!r && !recursion_stack.empty())
1794
0
   {
1795
0
      *m_presult = recursion_stack.back().results;
1796
0
      position = recursion_stack.back().location_of_start;
1797
0
      recursion_stack.pop_back();
1798
0
   }
1799
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
1800
0
   m_backup_state = pmp;
1801
0
   return true;
1802
0
}
1803
1804
template <class BidiIterator, class Allocator, class traits>
1805
void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_pop()
1806
0
{
1807
0
   saved_state* pmp = static_cast<saved_state*>(m_backup_state);
1808
0
   --pmp;
1809
0
   if(pmp < m_stack_base)
1810
0
   {
1811
0
      extend_stack();
1812
0
      pmp = static_cast<saved_state*>(m_backup_state);
1813
0
      --pmp;
1814
0
   }
1815
0
   (void) new (pmp)saved_state(15);
1816
0
   m_backup_state = pmp;
1817
0
}
1818
1819
template <class BidiIterator, class Allocator, class traits>
1820
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_commit(bool b)
1821
0
{
1822
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);
1823
0
   while(unwind(b) && !m_unwound_lookahead){}
1824
0
   if(m_unwound_lookahead && pstate)
1825
0
   {
1826
      //
1827
      // If we stop because we just unwound an assertion, put the
1828
      // commit state back on the stack again:
1829
      //
1830
0
      m_unwound_lookahead = false;
1831
0
      saved_state* pmp = m_backup_state;
1832
0
      --pmp;
1833
0
      if(pmp < m_stack_base)
1834
0
      {
1835
0
         extend_stack();
1836
0
         pmp = m_backup_state;
1837
0
         --pmp;
1838
0
      }
1839
0
      (void) new (pmp)saved_state(16);
1840
0
      m_backup_state = pmp;
1841
0
   }
1842
   // This prevents us from stopping when we exit from an independent sub-expression:
1843
0
   m_independent = false;
1844
0
   return false;
1845
0
}
1846
1847
template <class BidiIterator, class Allocator, class traits>
1848
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_then(bool b)
1849
0
{
1850
   // Unwind everything till we hit an alternative:
1851
0
   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);
1852
0
   bool result = false;
1853
0
   result = unwind(b);
1854
0
   while(result && !m_unwound_alt)
1855
0
   {
1856
0
      result = unwind(b);
1857
0
   }
1858
   // We're now pointing at the next alternative, need one more backtrack 
1859
   // since *all* the other alternatives must fail once we've reached a THEN clause:
1860
0
   if(result && m_unwound_alt)
1861
0
      unwind(b);
1862
0
   return false;
1863
0
}
1864
1865
} // namespace BOOST_REGEX_DETAIL_NS
1866
} // namespace boost
1867
1868
#ifdef BOOST_REGEX_MSVC
1869
#  pragma warning(pop)
1870
#endif
1871
1872
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/primary_transform.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 1998-2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
 
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE:        primary_transform.hpp
15
  *   VERSION:     see <boost/version.hpp>
16
  *   DESCRIPTION: Heuristically determines the sort string format in use
17
  *                by the current locale.
18
  */
19
20
#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
21
#define BOOST_REGEX_PRIMARY_TRANSFORM
22
23
namespace boost{
24
   namespace BOOST_REGEX_DETAIL_NS{
25
26
27
enum{
28
   sort_C,
29
   sort_fixed,
30
   sort_delim,
31
   sort_unknown
32
};
33
34
template <class S, class charT>
35
unsigned count_chars(const S& s, charT c)
36
0
{
37
   //
38
   // Count how many occurrences of character c occur
39
   // in string s: if c is a delimeter between collation
40
   // fields, then this should be the same value for all
41
   // sort keys:
42
   //
43
0
   unsigned int count = 0;
44
0
   for(unsigned pos = 0; pos < s.size(); ++pos)
45
0
   {
46
0
      if(s[pos] == c) ++count;
47
0
   }
48
0
   return count;
49
0
}
Unexecuted instantiation: _ZN5boost13re_detail_50011count_charsINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEcEEjRKT_T0_
Unexecuted instantiation: _ZN5boost13re_detail_50011count_charsINSt3__112basic_stringIwNS2_11char_traitsIwEENS2_9allocatorIwEEEEwEEjRKT_T0_
50
51
52
template <class traits, class charT>
53
unsigned find_sort_syntax(const traits* pt, charT* delim)
54
1
{
55
   //
56
   // compare 'a' with 'A' to see how similar they are,
57
   // should really use a-accute but we can't portably do that,
58
   //
59
1
   typedef typename traits::string_type string_type;
60
1
   typedef typename traits::char_type char_type;
61
62
   // Suppress incorrect warning for MSVC
63
1
   (void)pt;
64
65
1
   char_type a[2] = {'a', '\0', };
66
1
   string_type sa(pt->transform(a, a+1));
67
1
   if(sa == a)
68
0
   {
69
0
      *delim = 0;
70
0
      return sort_C;
71
0
   }
72
1
   char_type A[2] = { 'A', '\0', };
73
1
   string_type sA(pt->transform(A, A+1));
74
1
   char_type c[2] = { ';', '\0', };
75
1
   string_type sc(pt->transform(c, c+1));
76
77
1
   int pos = 0;
78
1
   while((pos <= static_cast<int>(sa.size())) && (pos <= static_cast<int>(sA.size())) && (sa[pos] == sA[pos])) ++pos;
79
1
   --pos;
80
1
   if(pos < 0)
81
1
   {
82
1
      *delim = 0;
83
1
      return sort_unknown;
84
1
   }
85
   //
86
   // at this point sa[pos] is either the end of a fixed width field
87
   // or the character that acts as a delimiter:
88
   //
89
0
   charT maybe_delim = sa[pos];
90
0
   if((pos != 0) && (count_chars(sa, maybe_delim) == count_chars(sA, maybe_delim)) && (count_chars(sa, maybe_delim) == count_chars(sc, maybe_delim)))
91
0
   {
92
0
      *delim = maybe_delim;
93
0
      return sort_delim;
94
0
   }
95
   //
96
   // OK doen't look like a delimiter, try for fixed width field:
97
   //
98
0
   if((sa.size() == sA.size()) && (sa.size() == sc.size()))
99
0
   {
100
      // note assumes that the fixed width field is less than
101
      // (numeric_limits<charT>::max)(), should be true for all types
102
      // I can't imagine 127 character fields...
103
0
      *delim = static_cast<charT>(++pos);
104
0
      return sort_fixed;
105
0
   }
106
   //
107
   // don't know what it is:
108
   //
109
0
   *delim = 0;
110
0
   return sort_unknown;
111
0
}
_ZN5boost13re_detail_50016find_sort_syntaxINS0_31cpp_regex_traits_implementationIcEEcEEjPKT_PT0_
Line
Count
Source
54
1
{
55
   //
56
   // compare 'a' with 'A' to see how similar they are,
57
   // should really use a-accute but we can't portably do that,
58
   //
59
1
   typedef typename traits::string_type string_type;
60
1
   typedef typename traits::char_type char_type;
61
62
   // Suppress incorrect warning for MSVC
63
1
   (void)pt;
64
65
1
   char_type a[2] = {'a', '\0', };
66
1
   string_type sa(pt->transform(a, a+1));
67
1
   if(sa == a)
68
0
   {
69
0
      *delim = 0;
70
0
      return sort_C;
71
0
   }
72
1
   char_type A[2] = { 'A', '\0', };
73
1
   string_type sA(pt->transform(A, A+1));
74
1
   char_type c[2] = { ';', '\0', };
75
1
   string_type sc(pt->transform(c, c+1));
76
77
1
   int pos = 0;
78
1
   while((pos <= static_cast<int>(sa.size())) && (pos <= static_cast<int>(sA.size())) && (sa[pos] == sA[pos])) ++pos;
79
1
   --pos;
80
1
   if(pos < 0)
81
1
   {
82
1
      *delim = 0;
83
1
      return sort_unknown;
84
1
   }
85
   //
86
   // at this point sa[pos] is either the end of a fixed width field
87
   // or the character that acts as a delimiter:
88
   //
89
0
   charT maybe_delim = sa[pos];
90
0
   if((pos != 0) && (count_chars(sa, maybe_delim) == count_chars(sA, maybe_delim)) && (count_chars(sa, maybe_delim) == count_chars(sc, maybe_delim)))
91
0
   {
92
0
      *delim = maybe_delim;
93
0
      return sort_delim;
94
0
   }
95
   //
96
   // OK doen't look like a delimiter, try for fixed width field:
97
   //
98
0
   if((sa.size() == sA.size()) && (sa.size() == sc.size()))
99
0
   {
100
      // note assumes that the fixed width field is less than
101
      // (numeric_limits<charT>::max)(), should be true for all types
102
      // I can't imagine 127 character fields...
103
0
      *delim = static_cast<charT>(++pos);
104
0
      return sort_fixed;
105
0
   }
106
   //
107
   // don't know what it is:
108
   //
109
0
   *delim = 0;
110
0
   return sort_unknown;
111
0
}
Unexecuted instantiation: _ZN5boost13re_detail_50016find_sort_syntaxINS_14c_regex_traitsIcEEcEEjPKT_PT0_
Unexecuted instantiation: _ZN5boost13re_detail_50016find_sort_syntaxINS_14c_regex_traitsIwEEwEEjPKT_PT0_
112
113
114
   } // namespace BOOST_REGEX_DETAIL_NS
115
} // namespace boost
116
117
#endif
118
119
120
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/regex_match.hpp
Line
Count
Source
1
/*
2
 *
3
 * Copyright (c) 1998-2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         regex_match.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Regular expression matching algorithms.
17
  *                Note this is an internal header file included
18
  *                by regex.hpp, do not include on its own.
19
  */
20
21
22
#ifndef BOOST_REGEX_MATCH_HPP
23
#define BOOST_REGEX_MATCH_HPP
24
25
namespace boost{
26
27
//
28
// proc regex_match
29
// returns true if the specified regular expression matches
30
// the whole of the input.  Fills in what matched in m.
31
//
32
template <class BidiIterator, class Allocator, class charT, class traits>
33
bool regex_match(BidiIterator first, BidiIterator last, 
34
                 match_results<BidiIterator, Allocator>& m, 
35
                 const basic_regex<charT, traits>& e, 
36
                 match_flag_type flags = match_default)
37
5
{
38
5
   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, first);
39
5
   return matcher.match();
40
5
}
41
template <class iterator, class charT, class traits>
42
bool regex_match(iterator first, iterator last, 
43
                 const basic_regex<charT, traits>& e, 
44
                 match_flag_type flags = match_default)
45
{
46
   match_results<iterator> m;
47
   return regex_match(first, last, m, e, flags | regex_constants::match_any);
48
}
49
//
50
// query_match convenience interfaces:
51
//
52
template <class charT, class Allocator, class traits>
53
inline bool regex_match(const charT* str, 
54
                        match_results<const charT*, Allocator>& m, 
55
                        const basic_regex<charT, traits>& e, 
56
                        match_flag_type flags = match_default)
57
{
58
   return regex_match(str, str + traits::length(str), m, e, flags);
59
}
60
61
template <class ST, class SA, class Allocator, class charT, class traits>
62
inline bool regex_match(const std::basic_string<charT, ST, SA>& s, 
63
                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, 
64
                 const basic_regex<charT, traits>& e, 
65
                 match_flag_type flags = match_default)
66
{
67
   return regex_match(s.begin(), s.end(), m, e, flags);
68
}
69
template <class charT, class traits>
70
inline bool regex_match(const charT* str, 
71
                        const basic_regex<charT, traits>& e, 
72
                        match_flag_type flags = match_default)
73
{
74
   match_results<const charT*> m;
75
   return regex_match(str, str + traits::length(str), m, e, flags | regex_constants::match_any);
76
}
77
78
template <class ST, class SA, class charT, class traits>
79
inline bool regex_match(const std::basic_string<charT, ST, SA>& s, 
80
                 const basic_regex<charT, traits>& e, 
81
                 match_flag_type flags = match_default)
82
5
{
83
5
   typedef typename std::basic_string<charT, ST, SA>::const_iterator iterator;
84
5
   match_results<iterator> m;
85
5
   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
86
5
}
87
88
89
} // namespace boost
90
91
#endif   // BOOST_REGEX_MATCH_HPP
92
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/regex_raw_buffer.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 1998-2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         regex_raw_buffer.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Raw character buffer for regex code.
17
  *                Note this is an internal header file included
18
  *                by regex.hpp, do not include on its own.
19
  */
20
21
#ifndef BOOST_REGEX_RAW_BUFFER_HPP
22
#define BOOST_REGEX_RAW_BUFFER_HPP
23
24
#ifndef BOOST_REGEX_CONFIG_HPP
25
#include <boost/regex/config.hpp>
26
#endif
27
28
#include <algorithm>
29
#include <cstddef>
30
31
namespace boost{
32
   namespace BOOST_REGEX_DETAIL_NS{
33
34
struct empty_padding{};
35
36
union padding
37
{
38
   void* p;
39
   unsigned int i;
40
};
41
42
template <int N>
43
struct padding3
44
{
45
   enum{
46
      padding_size = 8,
47
      padding_mask = 7
48
   };
49
};
50
51
template<>
52
struct padding3<2>
53
{
54
   enum{
55
      padding_size = 2,
56
      padding_mask = 1
57
   };
58
};
59
60
template<>
61
struct padding3<4>
62
{
63
   enum{
64
      padding_size = 4,
65
      padding_mask = 3
66
   };
67
};
68
69
template<>
70
struct padding3<8>
71
{
72
   enum{
73
      padding_size = 8,
74
      padding_mask = 7
75
   };
76
};
77
78
template<>
79
struct padding3<16>
80
{
81
   enum{
82
      padding_size = 16,
83
      padding_mask = 15
84
   };
85
};
86
87
enum{
88
   padding_size = padding3<sizeof(padding)>::padding_size,
89
   padding_mask = padding3<sizeof(padding)>::padding_mask
90
};
91
92
//
93
// class raw_storage
94
// basically this is a simplified vector<unsigned char>
95
// this is used by basic_regex for expression storage
96
//
97
98
class raw_storage
99
{
100
public:
101
   typedef std::size_t           size_type;
102
   typedef unsigned char*        pointer;
103
private:
104
   pointer last, start, end;
105
public:
106
107
   raw_storage();
108
   raw_storage(size_type n);
109
110
   ~raw_storage()
111
5
   {
112
5
      ::operator delete(start);
113
5
   }
114
115
   void  resize(size_type n)
116
10
   {
117
10
      size_type newsize = start ? last - start : 1024;
118
15
      while (newsize < n)
119
5
         newsize *= 2;
120
10
      size_type datasize = end - start;
121
      // extend newsize to WORD/DWORD boundary:
122
10
      newsize = (newsize + padding_mask) & ~(padding_mask);
123
124
      // allocate and copy data:
125
10
      pointer ptr = static_cast<pointer>(::operator new(newsize));
126
10
      BOOST_REGEX_NOEH_ASSERT(ptr)
127
10
         if (start)
128
5
            std::memcpy(ptr, start, datasize);
129
130
      // get rid of old buffer:
131
10
      ::operator delete(start);
132
133
      // and set up pointers:
134
10
      start = ptr;
135
10
      end = ptr + datasize;
136
10
      last = ptr + newsize;
137
10
   }
138
139
   void*  extend(size_type n)
140
65
   {
141
65
      if(size_type(last - end) < n)
142
5
         resize(n + (end - start));
143
65
      pointer result = end;
144
65
      end += n;
145
65
      return result;
146
65
   }
147
148
   void*  insert(size_type pos, size_type n)
149
10
   {
150
10
      BOOST_REGEX_ASSERT(pos <= size_type(end - start));
151
10
      if (size_type(last - end) < n)
152
5
         resize(n + (end - start));
153
10
      void* result = start + pos;
154
10
      std::memmove(start + pos + n, start + pos, (end - start) - pos);
155
10
      end += n;
156
10
      return result;
157
10
   }
158
159
   size_type  size()
160
90
   {
161
90
      return size_type(end - start);
162
90
   }
163
164
   size_type  capacity()
165
0
   {
166
0
      return size_type(last - start);
167
0
   }
168
169
   void*  data()const
170
130
   {
171
130
      return start;
172
130
   }
173
174
   size_type  index(void* ptr)
175
0
   {
176
0
      return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));
177
0
   }
178
179
   void  clear()
180
5
   {
181
5
      end = start;
182
5
   }
183
184
   void  align()
185
85
   {
186
      // move end up to a boundary:
187
85
      end = start + (((end - start) + padding_mask) & ~padding_mask);
188
85
   }
189
   void swap(raw_storage& that)
190
0
   {
191
0
      std::swap(start, that.start);
192
0
      std::swap(end, that.end);
193
0
      std::swap(last, that.last);
194
0
  }
195
};
196
197
inline raw_storage::raw_storage()
198
5
{
199
5
   last = start = end = 0;
200
5
}
201
202
inline raw_storage::raw_storage(size_type n)
203
{
204
   start = end = static_cast<pointer>(::operator new(n));
205
   BOOST_REGEX_NOEH_ASSERT(start)
206
   last = start + n;
207
}
208
209
} // namespace BOOST_REGEX_DETAIL_NS
210
} // namespace boost
211
212
#endif
213
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/regex_traits.hpp
Line
Count
Source
1
/*
2
 *
3
 * Copyright (c) 2003
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
 
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         regex_traits.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares regular expression traits classes.
17
  */
18
19
#ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED
20
#define BOOST_REGEX_TRAITS_HPP_INCLUDED
21
22
#include <boost/regex/config.hpp>
23
#include <boost/regex/v5/regex_workaround.hpp>
24
#include <boost/regex/v5/syntax_type.hpp>
25
#include <boost/regex/v5/error_type.hpp>
26
#include <boost/regex/v5/regex_traits_defaults.hpp>
27
#include <boost/regex/v5/cpp_regex_traits.hpp>
28
#include <boost/regex/v5/c_regex_traits.hpp>
29
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
30
#     include <boost/regex/v5/w32_regex_traits.hpp>
31
#endif
32
#include <boost/regex_fwd.hpp>
33
34
namespace boost{
35
36
template <class charT, class implementationT >
37
struct regex_traits : public implementationT
38
{
39
5
   regex_traits() : implementationT() {}
40
};
41
42
//
43
// class regex_traits_wrapper.
44
// this is what our implementation will actually store;
45
// it provides default implementations of the "optional"
46
// interfaces that we support, in addition to the
47
// required "standard" ones:
48
//
49
namespace BOOST_REGEX_DETAIL_NS{
50
51
   template <class T>
52
   struct has_boost_extensions_tag
53
   {
54
      template <class U>
55
      static double checker(U*, typename U::boost_extensions_tag* = nullptr);
56
      static char   checker(...);
57
      static T* get();
58
59
      static const bool value = sizeof(checker(get())) > 1;
60
   };
61
   
62
63
template <class BaseT>
64
struct default_wrapper : public BaseT
65
{
66
   typedef typename BaseT::char_type char_type;
67
   std::string error_string(::boost::regex_constants::error_type e)const
68
   {
69
      return ::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(e);
70
   }
71
   ::boost::regex_constants::syntax_type syntax_type(char_type c)const
72
   {
73
      return (char_type(c & 0x7f) == c) ? get_default_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::syntax_char;
74
   }
75
   ::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c)const
76
   {
77
      return (char_type(c & 0x7f) == c) ? get_default_escape_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::escape_type_identity;
78
   }
79
   std::intmax_t toi(const char_type*& p1, const char_type* p2, int radix)const
80
   {
81
      return ::boost::BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);
82
   }
83
   char_type translate(char_type c, bool icase)const
84
   {
85
      return (icase ? this->translate_nocase(c) : this->translate(c));
86
   }
87
   char_type translate(char_type c)const
88
   {
89
      return BaseT::translate(c);
90
   }
91
   char_type tolower(char_type c)const
92
   {
93
      return ::boost::BOOST_REGEX_DETAIL_NS::global_lower(c);
94
   }
95
   char_type toupper(char_type c)const
96
   {
97
      return ::boost::BOOST_REGEX_DETAIL_NS::global_upper(c);
98
   }
99
};
100
101
template <class BaseT, bool has_extensions>
102
struct compute_wrapper_base
103
{
104
   typedef BaseT type;
105
};
106
template <class BaseT>
107
struct compute_wrapper_base<BaseT, false>
108
{
109
   typedef default_wrapper<BaseT> type;
110
};
111
112
} // namespace BOOST_REGEX_DETAIL_NS
113
114
template <class BaseT>
115
struct regex_traits_wrapper 
116
   : public ::boost::BOOST_REGEX_DETAIL_NS::compute_wrapper_base<
117
               BaseT, 
118
               ::boost::BOOST_REGEX_DETAIL_NS::has_boost_extensions_tag<BaseT>::value
119
            >::type
120
{
121
5
   regex_traits_wrapper(){}
122
private:
123
   regex_traits_wrapper(const regex_traits_wrapper&);
124
   regex_traits_wrapper& operator=(const regex_traits_wrapper&);
125
};
126
127
} // namespace boost
128
129
#endif // include
130
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/regex_traits_defaults.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2004
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the
7
 * Boost Software License, Version 1.0. (See accompanying file
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         regex_traits_defaults.hpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares API's for access to regex_traits default properties.
17
  */
18
19
#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
20
#define BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
21
22
#include <boost/regex/config.hpp>
23
24
#include <boost/regex/v5/syntax_type.hpp>
25
#include <boost/regex/v5/error_type.hpp>
26
#include <boost/regex/v5/regex_workaround.hpp>
27
#include <type_traits>
28
#include <cstdint>
29
#include <cctype>
30
#include <locale>
31
#include <cwctype>
32
#include <limits>
33
34
namespace boost{ namespace BOOST_REGEX_DETAIL_NS{
35
36
37
//
38
// helpers to suppress warnings:
39
//
40
template <class charT>
41
inline bool is_extended(charT c)
42
{
43
   typedef typename std::make_unsigned<charT>::type unsigned_type; 
44
   return (sizeof(charT) > 1) && (static_cast<unsigned_type>(c) >= 256u); 
45
}
46
inline bool is_extended(char)
47
0
{ return false; }
48
49
inline const char*  get_default_syntax(regex_constants::syntax_type n)
50
59
{
51
   // if the user hasn't supplied a message catalog, then this supplies
52
   // default "messages" for us to load in the range 1-100.
53
59
   const char* messages[] = {
54
59
         "",
55
59
         "(",
56
59
         ")",
57
59
         "$",
58
59
         "^",
59
59
         ".",
60
59
         "*",
61
59
         "+",
62
59
         "?",
63
59
         "[",
64
59
         "]",
65
59
         "|",
66
59
         "\\",
67
59
         "#",
68
59
         "-",
69
59
         "{",
70
59
         "}",
71
59
         "0123456789",
72
59
         "b",
73
59
         "B",
74
59
         "<",
75
59
         ">",
76
59
         "",
77
59
         "",
78
59
         "A`",
79
59
         "z'",
80
59
         "\n",
81
59
         ",",
82
59
         "a",
83
59
         "f",
84
59
         "n",
85
59
         "r",
86
59
         "t",
87
59
         "v",
88
59
         "x",
89
59
         "c",
90
59
         ":",
91
59
         "=",
92
59
         "e",
93
59
         "",
94
59
         "",
95
59
         "",
96
59
         "",
97
59
         "",
98
59
         "",
99
59
         "",
100
59
         "",
101
59
         "E",
102
59
         "Q",
103
59
         "X",
104
59
         "C",
105
59
         "Z",
106
59
         "G",
107
59
         "!",
108
59
         "p",
109
59
         "P",
110
59
         "N",
111
59
         "gk",
112
59
         "K",
113
59
         "R",
114
59
   };
115
116
59
   return ((n >= (sizeof(messages) / sizeof(messages[1]))) ? "" : messages[n]);
117
59
}
118
119
inline const char*  get_default_error_string(regex_constants::error_type n)
120
0
{
121
0
   static const char* const s_default_error_messages[] = {
122
0
      "Success",                                                            /* REG_NOERROR 0 error_ok */
123
0
      "No match",                                                           /* REG_NOMATCH 1 error_no_match */
124
0
      "Invalid regular expression.",                                        /* REG_BADPAT 2 error_bad_pattern */
125
0
      "Invalid collation character.",                                       /* REG_ECOLLATE 3 error_collate */
126
0
      "Invalid character class name, collating name, or character range.",  /* REG_ECTYPE 4 error_ctype */
127
0
      "Invalid or unterminated escape sequence.",                           /* REG_EESCAPE 5 error_escape */
128
0
      "Invalid back reference: specified capturing group does not exist.",  /* REG_ESUBREG 6 error_backref */
129
0
      "Unmatched [ or [^ in character class declaration.",                  /* REG_EBRACK 7 error_brack */
130
0
      "Unmatched marking parenthesis ( or \\(.",                            /* REG_EPAREN 8 error_paren */
131
0
      "Unmatched quantified repeat operator { or \\{.",                     /* REG_EBRACE 9 error_brace */
132
0
      "Invalid content of repeat range.",                                   /* REG_BADBR 10 error_badbrace */
133
0
      "Invalid range end in character class",                               /* REG_ERANGE 11 error_range */
134
0
      "Out of memory.",                                                     /* REG_ESPACE 12 error_space NOT USED */
135
0
      "Invalid preceding regular expression prior to repetition operator.", /* REG_BADRPT 13 error_badrepeat */
136
0
      "Premature end of regular expression",                                /* REG_EEND 14 error_end NOT USED */
137
0
      "Regular expression is too large.",                                   /* REG_ESIZE 15 error_size NOT USED */
138
0
      "Unmatched ) or \\)",                                                 /* REG_ERPAREN 16 error_right_paren NOT USED */
139
0
      "Empty regular expression.",                                          /* REG_EMPTY 17 error_empty */
140
0
      "The complexity of matching the regular expression exceeded predefined bounds.  "
141
0
      "Try refactoring the regular expression to make each choice made by the state machine unambiguous.  "
142
0
      "This exception is thrown to prevent \"eternal\" matches that take an "
143
0
      "indefinite period time to locate.",                                  /* REG_ECOMPLEXITY 18 error_complexity */
144
0
      "Ran out of stack space trying to match the regular expression.",     /* REG_ESTACK 19 error_stack */
145
0
      "Invalid or unterminated Perl (?...) sequence.",                      /* REG_E_PERL 20 error_perl */
146
0
      "Unknown error.",                                                     /* REG_E_UNKNOWN 21 error_unknown */
147
0
   };
148
149
0
   return (n > ::boost::regex_constants::error_unknown) ? s_default_error_messages[::boost::regex_constants::error_unknown] : s_default_error_messages[n];
150
0
}
151
152
inline regex_constants::syntax_type  get_default_syntax_type(char c)
153
0
{
154
0
   //
155
0
   // char_syntax determines how the compiler treats a given character
156
0
   // in a regular expression.
157
0
   //
158
0
   static regex_constants::syntax_type char_syntax[] = {
159
0
      regex_constants::syntax_char,        /**/
160
0
      regex_constants::syntax_char,        /**/
161
0
      regex_constants::syntax_char,        /**/
162
0
      regex_constants::syntax_char,        /**/
163
0
      regex_constants::syntax_char,        /**/
164
0
      regex_constants::syntax_char,        /**/
165
0
      regex_constants::syntax_char,        /**/
166
0
      regex_constants::syntax_char,        /**/
167
0
      regex_constants::syntax_char,        /**/
168
0
      regex_constants::syntax_char,        /**/
169
0
      regex_constants::syntax_newline,     /**/
170
0
      regex_constants::syntax_char,        /**/
171
0
      regex_constants::syntax_char,        /**/
172
0
      regex_constants::syntax_char,        /**/
173
0
      regex_constants::syntax_char,        /**/
174
0
      regex_constants::syntax_char,        /**/
175
0
      regex_constants::syntax_char,        /**/
176
0
      regex_constants::syntax_char,        /**/
177
0
      regex_constants::syntax_char,        /**/
178
0
      regex_constants::syntax_char,        /**/
179
0
      regex_constants::syntax_char,        /**/
180
0
      regex_constants::syntax_char,        /**/
181
0
      regex_constants::syntax_char,        /**/
182
0
      regex_constants::syntax_char,        /**/
183
0
      regex_constants::syntax_char,        /**/
184
0
      regex_constants::syntax_char,        /**/
185
0
      regex_constants::syntax_char,        /**/
186
0
      regex_constants::syntax_char,        /**/
187
0
      regex_constants::syntax_char,        /**/
188
0
      regex_constants::syntax_char,        /**/
189
0
      regex_constants::syntax_char,        /**/
190
0
      regex_constants::syntax_char,        /**/
191
0
      regex_constants::syntax_char,        /* */    // 32
192
0
      regex_constants::syntax_not,        /*!*/
193
0
      regex_constants::syntax_char,        /*"*/
194
0
      regex_constants::syntax_hash,        /*#*/
195
0
      regex_constants::syntax_dollar,        /*$*/
196
0
      regex_constants::syntax_char,        /*%*/
197
0
      regex_constants::syntax_char,        /*&*/
198
0
      regex_constants::escape_type_end_buffer,  /*'*/
199
0
      regex_constants::syntax_open_mark,        /*(*/
200
0
      regex_constants::syntax_close_mark,        /*)*/
201
0
      regex_constants::syntax_star,        /***/
202
0
      regex_constants::syntax_plus,        /*+*/
203
0
      regex_constants::syntax_comma,        /*,*/
204
0
      regex_constants::syntax_dash,        /*-*/
205
0
      regex_constants::syntax_dot,        /*.*/
206
0
      regex_constants::syntax_char,        /*/*/
207
0
      regex_constants::syntax_digit,        /*0*/
208
0
      regex_constants::syntax_digit,        /*1*/
209
0
      regex_constants::syntax_digit,        /*2*/
210
0
      regex_constants::syntax_digit,        /*3*/
211
0
      regex_constants::syntax_digit,        /*4*/
212
0
      regex_constants::syntax_digit,        /*5*/
213
0
      regex_constants::syntax_digit,        /*6*/
214
0
      regex_constants::syntax_digit,        /*7*/
215
0
      regex_constants::syntax_digit,        /*8*/
216
0
      regex_constants::syntax_digit,        /*9*/
217
0
      regex_constants::syntax_colon,        /*:*/
218
0
      regex_constants::syntax_char,        /*;*/
219
0
      regex_constants::escape_type_left_word, /*<*/
220
0
      regex_constants::syntax_equal,        /*=*/
221
0
      regex_constants::escape_type_right_word, /*>*/
222
0
      regex_constants::syntax_question,        /*?*/
223
0
      regex_constants::syntax_char,        /*@*/
224
0
      regex_constants::syntax_char,        /*A*/
225
0
      regex_constants::syntax_char,        /*B*/
226
0
      regex_constants::syntax_char,        /*C*/
227
0
      regex_constants::syntax_char,        /*D*/
228
0
      regex_constants::syntax_char,        /*E*/
229
0
      regex_constants::syntax_char,        /*F*/
230
0
      regex_constants::syntax_char,        /*G*/
231
0
      regex_constants::syntax_char,        /*H*/
232
0
      regex_constants::syntax_char,        /*I*/
233
0
      regex_constants::syntax_char,        /*J*/
234
0
      regex_constants::syntax_char,        /*K*/
235
0
      regex_constants::syntax_char,        /*L*/
236
0
      regex_constants::syntax_char,        /*M*/
237
0
      regex_constants::syntax_char,        /*N*/
238
0
      regex_constants::syntax_char,        /*O*/
239
0
      regex_constants::syntax_char,        /*P*/
240
0
      regex_constants::syntax_char,        /*Q*/
241
0
      regex_constants::syntax_char,        /*R*/
242
0
      regex_constants::syntax_char,        /*S*/
243
0
      regex_constants::syntax_char,        /*T*/
244
0
      regex_constants::syntax_char,        /*U*/
245
0
      regex_constants::syntax_char,        /*V*/
246
0
      regex_constants::syntax_char,        /*W*/
247
0
      regex_constants::syntax_char,        /*X*/
248
0
      regex_constants::syntax_char,        /*Y*/
249
0
      regex_constants::syntax_char,        /*Z*/
250
0
      regex_constants::syntax_open_set,        /*[*/
251
0
      regex_constants::syntax_escape,        /*\*/
252
0
      regex_constants::syntax_close_set,        /*]*/
253
0
      regex_constants::syntax_caret,        /*^*/
254
0
      regex_constants::syntax_char,        /*_*/
255
0
      regex_constants::syntax_char,        /*`*/
256
0
      regex_constants::syntax_char,        /*a*/
257
0
      regex_constants::syntax_char,        /*b*/
258
0
      regex_constants::syntax_char,        /*c*/
259
0
      regex_constants::syntax_char,        /*d*/
260
0
      regex_constants::syntax_char,        /*e*/
261
0
      regex_constants::syntax_char,        /*f*/
262
0
      regex_constants::syntax_char,        /*g*/
263
0
      regex_constants::syntax_char,        /*h*/
264
0
      regex_constants::syntax_char,        /*i*/
265
0
      regex_constants::syntax_char,        /*j*/
266
0
      regex_constants::syntax_char,        /*k*/
267
0
      regex_constants::syntax_char,        /*l*/
268
0
      regex_constants::syntax_char,        /*m*/
269
0
      regex_constants::syntax_char,        /*n*/
270
0
      regex_constants::syntax_char,        /*o*/
271
0
      regex_constants::syntax_char,        /*p*/
272
0
      regex_constants::syntax_char,        /*q*/
273
0
      regex_constants::syntax_char,        /*r*/
274
0
      regex_constants::syntax_char,        /*s*/
275
0
      regex_constants::syntax_char,        /*t*/
276
0
      regex_constants::syntax_char,        /*u*/
277
0
      regex_constants::syntax_char,        /*v*/
278
0
      regex_constants::syntax_char,        /*w*/
279
0
      regex_constants::syntax_char,        /*x*/
280
0
      regex_constants::syntax_char,        /*y*/
281
0
      regex_constants::syntax_char,        /*z*/
282
0
      regex_constants::syntax_open_brace,        /*{*/
283
0
      regex_constants::syntax_or,        /*|*/
284
0
      regex_constants::syntax_close_brace,        /*}*/
285
0
      regex_constants::syntax_char,        /*~*/
286
0
      regex_constants::syntax_char,        /**/
287
0
      regex_constants::syntax_char,        /**/
288
0
      regex_constants::syntax_char,        /**/
289
0
      regex_constants::syntax_char,        /**/
290
0
      regex_constants::syntax_char,        /**/
291
0
      regex_constants::syntax_char,        /**/
292
0
      regex_constants::syntax_char,        /**/
293
0
      regex_constants::syntax_char,        /**/
294
0
      regex_constants::syntax_char,        /**/
295
0
      regex_constants::syntax_char,        /**/
296
0
      regex_constants::syntax_char,        /**/
297
0
      regex_constants::syntax_char,        /**/
298
0
      regex_constants::syntax_char,        /**/
299
0
      regex_constants::syntax_char,        /**/
300
0
      regex_constants::syntax_char,        /**/
301
0
      regex_constants::syntax_char,        /**/
302
0
      regex_constants::syntax_char,        /**/
303
0
      regex_constants::syntax_char,        /**/
304
0
      regex_constants::syntax_char,        /**/
305
0
      regex_constants::syntax_char,        /**/
306
0
      regex_constants::syntax_char,        /**/
307
0
      regex_constants::syntax_char,        /**/
308
0
      regex_constants::syntax_char,        /**/
309
0
      regex_constants::syntax_char,        /**/
310
0
      regex_constants::syntax_char,        /**/
311
0
      regex_constants::syntax_char,        /**/
312
0
      regex_constants::syntax_char,        /**/
313
0
      regex_constants::syntax_char,        /**/
314
0
      regex_constants::syntax_char,        /**/
315
0
      regex_constants::syntax_char,        /**/
316
0
      regex_constants::syntax_char,        /**/
317
0
      regex_constants::syntax_char,        /**/
318
0
      regex_constants::syntax_char,        /**/
319
0
      regex_constants::syntax_char,        /**/
320
0
      regex_constants::syntax_char,        /**/
321
0
      regex_constants::syntax_char,        /**/
322
0
      regex_constants::syntax_char,        /**/
323
0
      regex_constants::syntax_char,        /**/
324
0
      regex_constants::syntax_char,        /**/
325
0
      regex_constants::syntax_char,        /**/
326
0
      regex_constants::syntax_char,        /**/
327
0
      regex_constants::syntax_char,        /**/
328
0
      regex_constants::syntax_char,        /**/
329
0
      regex_constants::syntax_char,        /**/
330
0
      regex_constants::syntax_char,        /**/
331
0
      regex_constants::syntax_char,        /**/
332
0
      regex_constants::syntax_char,        /**/
333
0
      regex_constants::syntax_char,        /**/
334
0
      regex_constants::syntax_char,        /**/
335
0
      regex_constants::syntax_char,        /**/
336
0
      regex_constants::syntax_char,        /**/
337
0
      regex_constants::syntax_char,        /**/
338
0
      regex_constants::syntax_char,        /**/
339
0
      regex_constants::syntax_char,        /**/
340
0
      regex_constants::syntax_char,        /**/
341
0
      regex_constants::syntax_char,        /**/
342
0
   };
343
0
344
0
   return char_syntax[(unsigned char)c];
345
0
}
346
347
inline regex_constants::escape_syntax_type  get_default_escape_syntax_type(char c)
348
0
{
349
0
   //
350
0
   // char_syntax determines how the compiler treats a given character
351
0
   // in a regular expression.
352
0
   //
353
0
   static regex_constants::escape_syntax_type char_syntax[] = {
354
0
      regex_constants::escape_type_identity,        /**/
355
0
      regex_constants::escape_type_identity,        /**/
356
0
      regex_constants::escape_type_identity,        /**/
357
0
      regex_constants::escape_type_identity,        /**/
358
0
      regex_constants::escape_type_identity,        /**/
359
0
      regex_constants::escape_type_identity,        /**/
360
0
      regex_constants::escape_type_identity,        /**/
361
0
      regex_constants::escape_type_identity,        /**/
362
0
      regex_constants::escape_type_identity,        /**/
363
0
      regex_constants::escape_type_identity,        /**/
364
0
      regex_constants::escape_type_identity,     /**/
365
0
      regex_constants::escape_type_identity,        /**/
366
0
      regex_constants::escape_type_identity,        /**/
367
0
      regex_constants::escape_type_identity,        /**/
368
0
      regex_constants::escape_type_identity,        /**/
369
0
      regex_constants::escape_type_identity,        /**/
370
0
      regex_constants::escape_type_identity,        /**/
371
0
      regex_constants::escape_type_identity,        /**/
372
0
      regex_constants::escape_type_identity,        /**/
373
0
      regex_constants::escape_type_identity,        /**/
374
0
      regex_constants::escape_type_identity,        /**/
375
0
      regex_constants::escape_type_identity,        /**/
376
0
      regex_constants::escape_type_identity,        /**/
377
0
      regex_constants::escape_type_identity,        /**/
378
0
      regex_constants::escape_type_identity,        /**/
379
0
      regex_constants::escape_type_identity,        /**/
380
0
      regex_constants::escape_type_identity,        /**/
381
0
      regex_constants::escape_type_identity,        /**/
382
0
      regex_constants::escape_type_identity,        /**/
383
0
      regex_constants::escape_type_identity,        /**/
384
0
      regex_constants::escape_type_identity,        /**/
385
0
      regex_constants::escape_type_identity,        /**/
386
0
      regex_constants::escape_type_identity,        /* */    // 32
387
0
      regex_constants::escape_type_identity,        /*!*/
388
0
      regex_constants::escape_type_identity,        /*"*/
389
0
      regex_constants::escape_type_identity,        /*#*/
390
0
      regex_constants::escape_type_identity,        /*$*/
391
0
      regex_constants::escape_type_identity,        /*%*/
392
0
      regex_constants::escape_type_identity,        /*&*/
393
0
      regex_constants::escape_type_end_buffer,        /*'*/
394
0
      regex_constants::syntax_open_mark,        /*(*/
395
0
      regex_constants::syntax_close_mark,        /*)*/
396
0
      regex_constants::escape_type_identity,        /***/
397
0
      regex_constants::syntax_plus,                 /*+*/
398
0
      regex_constants::escape_type_identity,        /*,*/
399
0
      regex_constants::escape_type_identity,        /*-*/
400
0
      regex_constants::escape_type_identity,        /*.*/
401
0
      regex_constants::escape_type_identity,        /*/*/
402
0
      regex_constants::escape_type_decimal,        /*0*/
403
0
      regex_constants::escape_type_backref,        /*1*/
404
0
      regex_constants::escape_type_backref,        /*2*/
405
0
      regex_constants::escape_type_backref,        /*3*/
406
0
      regex_constants::escape_type_backref,        /*4*/
407
0
      regex_constants::escape_type_backref,        /*5*/
408
0
      regex_constants::escape_type_backref,        /*6*/
409
0
      regex_constants::escape_type_backref,        /*7*/
410
0
      regex_constants::escape_type_backref,        /*8*/
411
0
      regex_constants::escape_type_backref,        /*9*/
412
0
      regex_constants::escape_type_identity,        /*:*/
413
0
      regex_constants::escape_type_identity,        /*;*/
414
0
      regex_constants::escape_type_left_word,        /*<*/
415
0
      regex_constants::escape_type_identity,        /*=*/
416
0
      regex_constants::escape_type_right_word,        /*>*/
417
0
      regex_constants::syntax_question,              /*?*/
418
0
      regex_constants::escape_type_identity,         /*@*/
419
0
      regex_constants::escape_type_start_buffer,     /*A*/
420
0
      regex_constants::escape_type_not_word_assert,  /*B*/
421
0
      regex_constants::escape_type_C,                /*C*/
422
0
      regex_constants::escape_type_not_class,        /*D*/
423
0
      regex_constants::escape_type_E,                /*E*/
424
0
      regex_constants::escape_type_not_class,        /*F*/
425
0
      regex_constants::escape_type_G,                /*G*/
426
0
      regex_constants::escape_type_not_class,        /*H*/
427
0
      regex_constants::escape_type_not_class,        /*I*/
428
0
      regex_constants::escape_type_not_class,        /*J*/
429
0
      regex_constants::escape_type_reset_start_mark, /*K*/
430
0
      regex_constants::escape_type_not_class,        /*L*/
431
0
      regex_constants::escape_type_not_class,        /*M*/
432
0
      regex_constants::escape_type_named_char,       /*N*/
433
0
      regex_constants::escape_type_not_class,        /*O*/
434
0
      regex_constants::escape_type_not_property,     /*P*/
435
0
      regex_constants::escape_type_Q,                /*Q*/
436
0
      regex_constants::escape_type_line_ending,      /*R*/
437
0
      regex_constants::escape_type_not_class,        /*S*/
438
0
      regex_constants::escape_type_not_class,        /*T*/
439
0
      regex_constants::escape_type_not_class,        /*U*/
440
0
      regex_constants::escape_type_not_class,        /*V*/
441
0
      regex_constants::escape_type_not_class,        /*W*/
442
0
      regex_constants::escape_type_X,                /*X*/
443
0
      regex_constants::escape_type_not_class,        /*Y*/
444
0
      regex_constants::escape_type_Z,                /*Z*/
445
0
      regex_constants::escape_type_identity,        /*[*/
446
0
      regex_constants::escape_type_identity,        /*\*/
447
0
      regex_constants::escape_type_identity,        /*]*/
448
0
      regex_constants::escape_type_identity,        /*^*/
449
0
      regex_constants::escape_type_identity,        /*_*/
450
0
      regex_constants::escape_type_start_buffer,        /*`*/
451
0
      regex_constants::escape_type_control_a,        /*a*/
452
0
      regex_constants::escape_type_word_assert,        /*b*/
453
0
      regex_constants::escape_type_ascii_control,        /*c*/
454
0
      regex_constants::escape_type_class,        /*d*/
455
0
      regex_constants::escape_type_e,        /*e*/
456
0
      regex_constants::escape_type_control_f,       /*f*/
457
0
      regex_constants::escape_type_extended_backref,  /*g*/
458
0
      regex_constants::escape_type_class,        /*h*/
459
0
      regex_constants::escape_type_class,        /*i*/
460
0
      regex_constants::escape_type_class,        /*j*/
461
0
      regex_constants::escape_type_extended_backref, /*k*/
462
0
      regex_constants::escape_type_class,        /*l*/
463
0
      regex_constants::escape_type_class,        /*m*/
464
0
      regex_constants::escape_type_control_n,       /*n*/
465
0
      regex_constants::escape_type_class,           /*o*/
466
0
      regex_constants::escape_type_property,        /*p*/
467
0
      regex_constants::escape_type_class,           /*q*/
468
0
      regex_constants::escape_type_control_r,       /*r*/
469
0
      regex_constants::escape_type_class,           /*s*/
470
0
      regex_constants::escape_type_control_t,       /*t*/
471
0
      regex_constants::escape_type_class,         /*u*/
472
0
      regex_constants::escape_type_control_v,       /*v*/
473
0
      regex_constants::escape_type_class,           /*w*/
474
0
      regex_constants::escape_type_hex,             /*x*/
475
0
      regex_constants::escape_type_class,           /*y*/
476
0
      regex_constants::escape_type_end_buffer,      /*z*/
477
0
      regex_constants::syntax_open_brace,           /*{*/
478
0
      regex_constants::syntax_or,                   /*|*/
479
0
      regex_constants::syntax_close_brace,          /*}*/
480
0
      regex_constants::escape_type_identity,        /*~*/
481
0
      regex_constants::escape_type_identity,        /**/
482
0
      regex_constants::escape_type_identity,        /**/
483
0
      regex_constants::escape_type_identity,        /**/
484
0
      regex_constants::escape_type_identity,        /**/
485
0
      regex_constants::escape_type_identity,        /**/
486
0
      regex_constants::escape_type_identity,        /**/
487
0
      regex_constants::escape_type_identity,        /**/
488
0
      regex_constants::escape_type_identity,        /**/
489
0
      regex_constants::escape_type_identity,        /**/
490
0
      regex_constants::escape_type_identity,        /**/
491
0
      regex_constants::escape_type_identity,        /**/
492
0
      regex_constants::escape_type_identity,        /**/
493
0
      regex_constants::escape_type_identity,        /**/
494
0
      regex_constants::escape_type_identity,        /**/
495
0
      regex_constants::escape_type_identity,        /**/
496
0
      regex_constants::escape_type_identity,        /**/
497
0
      regex_constants::escape_type_identity,        /**/
498
0
      regex_constants::escape_type_identity,        /**/
499
0
      regex_constants::escape_type_identity,        /**/
500
0
      regex_constants::escape_type_identity,        /**/
501
0
      regex_constants::escape_type_identity,        /**/
502
0
      regex_constants::escape_type_identity,        /**/
503
0
      regex_constants::escape_type_identity,        /**/
504
0
      regex_constants::escape_type_identity,        /**/
505
0
      regex_constants::escape_type_identity,        /**/
506
0
      regex_constants::escape_type_identity,        /**/
507
0
      regex_constants::escape_type_identity,        /**/
508
0
      regex_constants::escape_type_identity,        /**/
509
0
      regex_constants::escape_type_identity,        /**/
510
0
      regex_constants::escape_type_identity,        /**/
511
0
      regex_constants::escape_type_identity,        /**/
512
0
      regex_constants::escape_type_identity,        /**/
513
0
      regex_constants::escape_type_identity,        /**/
514
0
      regex_constants::escape_type_identity,        /**/
515
0
      regex_constants::escape_type_identity,        /**/
516
0
      regex_constants::escape_type_identity,        /**/
517
0
      regex_constants::escape_type_identity,        /**/
518
0
      regex_constants::escape_type_identity,        /**/
519
0
      regex_constants::escape_type_identity,        /**/
520
0
      regex_constants::escape_type_identity,        /**/
521
0
      regex_constants::escape_type_identity,        /**/
522
0
      regex_constants::escape_type_identity,        /**/
523
0
      regex_constants::escape_type_identity,        /**/
524
0
      regex_constants::escape_type_identity,        /**/
525
0
      regex_constants::escape_type_identity,        /**/
526
0
      regex_constants::escape_type_identity,        /**/
527
0
      regex_constants::escape_type_identity,        /**/
528
0
      regex_constants::escape_type_identity,        /**/
529
0
      regex_constants::escape_type_identity,        /**/
530
0
      regex_constants::escape_type_identity,        /**/
531
0
      regex_constants::escape_type_identity,        /**/
532
0
      regex_constants::escape_type_identity,        /**/
533
0
      regex_constants::escape_type_identity,        /**/
534
0
      regex_constants::escape_type_identity,        /**/
535
0
      regex_constants::escape_type_identity,        /**/
536
0
      regex_constants::escape_type_identity,        /**/
537
0
   };
538
0
539
0
   return char_syntax[(unsigned char)c];
540
0
}
541
542
// is charT c a combining character?
543
inline bool  is_combining_implementation(std::uint_least16_t c)
544
0
{
545
0
   const std::uint_least16_t combining_ranges[] = { 0x0300, 0x0361,
546
0
                           0x0483, 0x0486,
547
0
                           0x0903, 0x0903,
548
0
                           0x093E, 0x0940,
549
0
                           0x0949, 0x094C,
550
0
                           0x0982, 0x0983,
551
0
                           0x09BE, 0x09C0,
552
0
                           0x09C7, 0x09CC,
553
0
                           0x09D7, 0x09D7,
554
0
                           0x0A3E, 0x0A40,
555
0
                           0x0A83, 0x0A83,
556
0
                           0x0ABE, 0x0AC0,
557
0
                           0x0AC9, 0x0ACC,
558
0
                           0x0B02, 0x0B03,
559
0
                           0x0B3E, 0x0B3E,
560
0
                           0x0B40, 0x0B40,
561
0
                           0x0B47, 0x0B4C,
562
0
                           0x0B57, 0x0B57,
563
0
                           0x0B83, 0x0B83,
564
0
                           0x0BBE, 0x0BBF,
565
0
                           0x0BC1, 0x0BCC,
566
0
                           0x0BD7, 0x0BD7,
567
0
                           0x0C01, 0x0C03,
568
0
                           0x0C41, 0x0C44,
569
0
                           0x0C82, 0x0C83,
570
0
                           0x0CBE, 0x0CBE,
571
0
                           0x0CC0, 0x0CC4,
572
0
                           0x0CC7, 0x0CCB,
573
0
                           0x0CD5, 0x0CD6,
574
0
                           0x0D02, 0x0D03,
575
0
                           0x0D3E, 0x0D40,
576
0
                           0x0D46, 0x0D4C,
577
0
                           0x0D57, 0x0D57,
578
0
                           0x0F7F, 0x0F7F,
579
0
                           0x20D0, 0x20E1,
580
0
                           0x3099, 0x309A,
581
0
                           0xFE20, 0xFE23,
582
0
                           0xffff, 0xffff, };
583
0
584
0
   const std::uint_least16_t* p = combining_ranges + 1;
585
0
   while (*p < c) p += 2;
586
0
   --p;
587
0
   if ((c >= *p) && (c <= *(p + 1)))
588
0
      return true;
589
0
   return false;
590
0
}
591
592
template <class charT>
593
inline bool is_combining(charT c)
594
{
595
   return (c <= static_cast<charT>(0)) ? false : ((c >= static_cast<charT>((std::numeric_limits<uint_least16_t>::max)())) ? false : is_combining_implementation(static_cast<unsigned short>(c)));
596
}
597
template <>
598
inline bool is_combining<char>(char)
599
0
{
600
0
   return false;
601
0
}
602
template <>
603
inline bool is_combining<signed char>(signed char)
604
0
{
605
0
   return false;
606
0
}
607
template <>
608
inline bool is_combining<unsigned char>(unsigned char)
609
0
{
610
0
   return false;
611
0
}
612
#ifdef _MSC_VER
613
template<>
614
inline bool is_combining<wchar_t>(wchar_t c)
615
{
616
   return is_combining_implementation(static_cast<unsigned short>(c));
617
}
618
#elif !defined(__DECCXX) && !defined(__osf__) && !defined(__OSF__) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
619
#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)
620
template<>
621
inline bool is_combining<wchar_t>(wchar_t c)
622
{
623
   return is_combining_implementation(static_cast<unsigned short>(c));
624
}
625
#else
626
template<>
627
inline bool is_combining<wchar_t>(wchar_t c)
628
{
629
   return (c >= (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c));
630
}
631
#endif
632
#endif
633
634
//
635
// is a charT c a line separator?
636
//
637
template <class charT>
638
inline bool is_separator(charT c)
639
0
{
640
0
   return BOOST_REGEX_MAKE_BOOL(
641
0
      (c == static_cast<charT>('\n'))
642
0
      || (c == static_cast<charT>('\r'))
643
0
      || (c == static_cast<charT>('\f'))
644
0
      || (static_cast<std::uint16_t>(c) == 0x2028u)
645
0
      || (static_cast<std::uint16_t>(c) == 0x2029u)
646
0
      || (static_cast<std::uint16_t>(c) == 0x85u));
647
0
}
648
template <>
649
inline bool is_separator<char>(char c)
650
0
{
651
0
   return BOOST_REGEX_MAKE_BOOL((c == '\n') || (c == '\r') || (c == '\f'));
652
0
}
653
654
//
655
// get a default collating element:
656
//
657
inline std::string  lookup_default_collate_name(const std::string& name)
658
0
{
659
   //
660
   // these are the POSIX collating names:
661
   //
662
0
   static const char* def_coll_names[] = {
663
0
   "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "alert", "backspace", "tab", "newline",
664
0
   "vertical-tab", "form-feed", "carriage-return", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK",
665
0
   "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "IS4", "IS3", "IS2", "IS1", "space", "exclamation-mark",
666
0
   "quotation-mark", "number-sign", "dollar-sign", "percent-sign", "ampersand", "apostrophe",
667
0
   "left-parenthesis", "right-parenthesis", "asterisk", "plus-sign", "comma", "hyphen",
668
0
   "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
669
0
   "colon", "semicolon", "less-than-sign", "equals-sign", "greater-than-sign",
670
0
   "question-mark", "commercial-at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
671
0
   "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "left-square-bracket", "backslash",
672
0
   "right-square-bracket", "circumflex", "underscore", "grave-accent", "a", "b", "c", "d", "e", "f",
673
0
   "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "left-curly-bracket",
674
0
   "vertical-line", "right-curly-bracket", "tilde", "DEL", "",
675
0
   };
676
677
   // these multi-character collating elements
678
   // should keep most Western-European locales
679
   // happy - we should really localise these a
680
   // little more - but this will have to do for
681
   // now:
682
683
0
   static const char* def_multi_coll[] = {
684
0
      "ae",
685
0
      "Ae",
686
0
      "AE",
687
0
      "ch",
688
0
      "Ch",
689
0
      "CH",
690
0
      "ll",
691
0
      "Ll",
692
0
      "LL",
693
0
      "ss",
694
0
      "Ss",
695
0
      "SS",
696
0
      "nj",
697
0
      "Nj",
698
0
      "NJ",
699
0
      "dz",
700
0
      "Dz",
701
0
      "DZ",
702
0
      "lj",
703
0
      "Lj",
704
0
      "LJ",
705
0
      "",
706
0
   };
707
708
0
   unsigned int i = 0;
709
0
   while (*def_coll_names[i])
710
0
   {
711
0
      if (def_coll_names[i] == name)
712
0
      {
713
0
         return std::string(1, char(i));
714
0
      }
715
0
      ++i;
716
0
   }
717
0
   i = 0;
718
0
   while (*def_multi_coll[i])
719
0
   {
720
0
      if (def_multi_coll[i] == name)
721
0
      {
722
0
         return def_multi_coll[i];
723
0
      }
724
0
      ++i;
725
0
   }
726
0
   return std::string();
727
0
}
728
729
//
730
// get the state_id of a character classification, the individual
731
// traits classes then transform that state_id into a bitmask:
732
//
733
template <class charT>
734
struct character_pointer_range
735
{
736
   const charT* p1;
737
   const charT* p2;
738
739
   bool operator < (const character_pointer_range& r)const
740
115
   {
741
115
      return std::lexicographical_compare(p1, p2, r.p1, r.p2);
742
115
   }
_ZNK5boost13re_detail_50023character_pointer_rangeIcEltERKS2_
Line
Count
Source
740
115
   {
741
115
      return std::lexicographical_compare(p1, p2, r.p1, r.p2);
742
115
   }
Unexecuted instantiation: _ZNK5boost13re_detail_50023character_pointer_rangeIwEltERKS2_
743
   bool operator == (const character_pointer_range& r)const
744
25
   {
745
      // Not only do we check that the ranges are of equal size before
746
      // calling std::equal, but there is no other algorithm available:
747
      // not even a non-standard MS one.  So forward to unchecked_equal
748
      // in the MS case.
749
25
#ifdef __cpp_lib_robust_nonmodifying_seq_ops
750
25
      return std::equal(p1, p2, r.p1, r.p2);
751
#elif defined(BOOST_REGEX_MSVC)
752
      if (((p2 - p1) != (r.p2 - r.p1)))
753
         return false;
754
      const charT* with = r.p1;
755
      const charT* pos = p1;
756
      while (pos != p2)
757
         if (*pos++ != *with++) return false;
758
      return true;
759
760
#else
761
      return ((p2 - p1) == (r.p2 - r.p1)) && std::equal(p1, p2, r.p1);
762
#endif
763
25
   }
_ZNK5boost13re_detail_50023character_pointer_rangeIcEeqERKS2_
Line
Count
Source
744
25
   {
745
      // Not only do we check that the ranges are of equal size before
746
      // calling std::equal, but there is no other algorithm available:
747
      // not even a non-standard MS one.  So forward to unchecked_equal
748
      // in the MS case.
749
25
#ifdef __cpp_lib_robust_nonmodifying_seq_ops
750
25
      return std::equal(p1, p2, r.p1, r.p2);
751
#elif defined(BOOST_REGEX_MSVC)
752
      if (((p2 - p1) != (r.p2 - r.p1)))
753
         return false;
754
      const charT* with = r.p1;
755
      const charT* pos = p1;
756
      while (pos != p2)
757
         if (*pos++ != *with++) return false;
758
      return true;
759
760
#else
761
      return ((p2 - p1) == (r.p2 - r.p1)) && std::equal(p1, p2, r.p1);
762
#endif
763
25
   }
Unexecuted instantiation: _ZNK5boost13re_detail_50023character_pointer_rangeIwEeqERKS2_
764
};
765
template <class charT>
766
int get_default_class_id(const charT* p1, const charT* p2)
767
25
{
768
25
   static const charT data[73] = {
769
25
      'a', 'l', 'n', 'u', 'm',
770
25
      'a', 'l', 'p', 'h', 'a',
771
25
      'b', 'l', 'a', 'n', 'k',
772
25
      'c', 'n', 't', 'r', 'l',
773
25
      'd', 'i', 'g', 'i', 't',
774
25
      'g', 'r', 'a', 'p', 'h',
775
25
      'l', 'o', 'w', 'e', 'r',
776
25
      'p', 'r', 'i', 'n', 't',
777
25
      'p', 'u', 'n', 'c', 't',
778
25
      's', 'p', 'a', 'c', 'e',
779
25
      'u', 'n', 'i', 'c', 'o', 'd', 'e',
780
25
      'u', 'p', 'p', 'e', 'r',
781
25
      'v',
782
25
      'w', 'o', 'r', 'd',
783
25
      'x', 'd', 'i', 'g', 'i', 't',
784
25
   };
785
786
25
   static const character_pointer_range<charT> ranges[21] =
787
25
   {
788
25
      {data+0, data+5,}, // alnum
789
25
      {data+5, data+10,}, // alpha
790
25
      {data+10, data+15,}, // blank
791
25
      {data+15, data+20,}, // cntrl
792
25
      {data+20, data+21,}, // d
793
25
      {data+20, data+25,}, // digit
794
25
      {data+25, data+30,}, // graph
795
25
      {data+29, data+30,}, // h
796
25
      {data+30, data+31,}, // l
797
25
      {data+30, data+35,}, // lower
798
25
      {data+35, data+40,}, // print
799
25
      {data+40, data+45,}, // punct
800
25
      {data+45, data+46,}, // s
801
25
      {data+45, data+50,}, // space
802
25
      {data+57, data+58,}, // u
803
25
      {data+50, data+57,}, // unicode
804
25
      {data+57, data+62,}, // upper
805
25
      {data+62, data+63,}, // v
806
25
      {data+63, data+64,}, // w
807
25
      {data+63, data+67,}, // word
808
25
      {data+67, data+73,}, // xdigit
809
25
   };
810
25
   const character_pointer_range<charT>* ranges_begin = ranges;
811
25
   const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));
812
813
25
   character_pointer_range<charT> t = { p1, p2, };
814
25
   const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);
815
25
   if((p != ranges_end) && (t == *p))
816
25
      return static_cast<int>(p - ranges);
817
0
   return -1;
818
25
}
_ZN5boost13re_detail_50020get_default_class_idIcEEiPKT_S4_
Line
Count
Source
767
25
{
768
25
   static const charT data[73] = {
769
25
      'a', 'l', 'n', 'u', 'm',
770
25
      'a', 'l', 'p', 'h', 'a',
771
25
      'b', 'l', 'a', 'n', 'k',
772
25
      'c', 'n', 't', 'r', 'l',
773
25
      'd', 'i', 'g', 'i', 't',
774
25
      'g', 'r', 'a', 'p', 'h',
775
25
      'l', 'o', 'w', 'e', 'r',
776
25
      'p', 'r', 'i', 'n', 't',
777
25
      'p', 'u', 'n', 'c', 't',
778
25
      's', 'p', 'a', 'c', 'e',
779
25
      'u', 'n', 'i', 'c', 'o', 'd', 'e',
780
25
      'u', 'p', 'p', 'e', 'r',
781
25
      'v',
782
25
      'w', 'o', 'r', 'd',
783
25
      'x', 'd', 'i', 'g', 'i', 't',
784
25
   };
785
786
25
   static const character_pointer_range<charT> ranges[21] =
787
25
   {
788
25
      {data+0, data+5,}, // alnum
789
25
      {data+5, data+10,}, // alpha
790
25
      {data+10, data+15,}, // blank
791
25
      {data+15, data+20,}, // cntrl
792
25
      {data+20, data+21,}, // d
793
25
      {data+20, data+25,}, // digit
794
25
      {data+25, data+30,}, // graph
795
25
      {data+29, data+30,}, // h
796
25
      {data+30, data+31,}, // l
797
25
      {data+30, data+35,}, // lower
798
25
      {data+35, data+40,}, // print
799
25
      {data+40, data+45,}, // punct
800
25
      {data+45, data+46,}, // s
801
25
      {data+45, data+50,}, // space
802
25
      {data+57, data+58,}, // u
803
25
      {data+50, data+57,}, // unicode
804
25
      {data+57, data+62,}, // upper
805
25
      {data+62, data+63,}, // v
806
25
      {data+63, data+64,}, // w
807
25
      {data+63, data+67,}, // word
808
25
      {data+67, data+73,}, // xdigit
809
25
   };
810
25
   const character_pointer_range<charT>* ranges_begin = ranges;
811
25
   const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));
812
813
25
   character_pointer_range<charT> t = { p1, p2, };
814
25
   const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);
815
25
   if((p != ranges_end) && (t == *p))
816
25
      return static_cast<int>(p - ranges);
817
0
   return -1;
818
25
}
Unexecuted instantiation: _ZN5boost13re_detail_50020get_default_class_idIwEEiPKT_S4_
819
820
//
821
// helper functions:
822
//
823
template <class charT>
824
std::ptrdiff_t global_length(const charT* p)
825
{
826
   std::ptrdiff_t n = 0;
827
   while(*p)
828
   {
829
      ++p;
830
      ++n;
831
   }
832
   return n;
833
}
834
template<>
835
inline std::ptrdiff_t global_length<char>(const char* p)
836
0
{
837
0
   return (std::strlen)(p);
838
0
}
839
#ifndef BOOST_NO_WREGEX
840
template<>
841
inline std::ptrdiff_t global_length<wchar_t>(const wchar_t* p)
842
0
{
843
0
   return (std::ptrdiff_t)(std::wcslen)(p);
844
0
}
845
#endif
846
template <class charT>
847
inline charT  global_lower(charT c)
848
{
849
   return c;
850
}
851
template <class charT>
852
inline charT  global_upper(charT c)
853
{
854
   return c;
855
}
856
857
inline char  do_global_lower(char c)
858
0
{
859
0
   return static_cast<char>((std::tolower)((unsigned char)c));
860
0
}
861
862
inline char  do_global_upper(char c)
863
0
{
864
0
   return static_cast<char>((std::toupper)((unsigned char)c));
865
0
}
866
#ifndef BOOST_NO_WREGEX
867
inline wchar_t  do_global_lower(wchar_t c)
868
0
{
869
0
   return (std::towlower)(c);
870
0
}
871
872
inline wchar_t  do_global_upper(wchar_t c)
873
0
{
874
0
   return (std::towupper)(c);
875
0
}
876
#endif
877
//
878
// This sucks: declare template specialisations of global_lower/global_upper
879
// that just forward to the non-template implementation functions.  We do
880
// this because there is one compiler (Compaq Tru64 C++) that doesn't seem
881
// to differentiate between templates and non-template overloads....
882
// what's more, the primary template, plus all overloads have to be
883
// defined in the same translation unit (if one is inline they all must be)
884
// otherwise the "local template instantiation" compiler option can pick
885
// the wrong instantiation when linking:
886
//
887
0
template<> inline char  global_lower<char>(char c) { return do_global_lower(c); }
888
0
template<> inline char  global_upper<char>(char c) { return do_global_upper(c); }
889
#ifndef BOOST_NO_WREGEX
890
0
template<> inline wchar_t  global_lower<wchar_t>(wchar_t c) { return do_global_lower(c); }
891
0
template<> inline wchar_t  global_upper<wchar_t>(wchar_t c) { return do_global_upper(c); }
892
#endif
893
894
template <class charT>
895
int global_value(charT c)
896
{
897
   static const charT zero = '0';
898
   static const charT nine = '9';
899
   static const charT a = 'a';
900
   static const charT f = 'f';
901
   static const charT A = 'A';
902
   static const charT F = 'F';
903
904
   if(c > f) return -1;
905
   if(c >= a) return 10 + (c - a);
906
   if(c > F) return -1;
907
   if(c >= A) return 10 + (c - A);
908
   if(c > nine) return -1;
909
   if(c >= zero) return c - zero;
910
   return -1;
911
}
912
template <class charT, class traits>
913
std::intmax_t global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)
914
{
915
   (void)t; // warning suppression
916
   std::intmax_t limit = (std::numeric_limits<std::intmax_t>::max)() / radix;
917
   std::intmax_t next_value = t.value(*p1, radix);
918
   if((p1 == p2) || (next_value < 0) || (next_value >= radix))
919
      return -1;
920
   std::intmax_t result = 0;
921
   while(p1 != p2)
922
   {
923
      next_value = t.value(*p1, radix);
924
      if((next_value < 0) || (next_value >= radix))
925
         break;
926
      result *= radix;
927
      result += next_value;
928
      ++p1;
929
      if (result > limit)
930
         return -1;
931
   }
932
   return result;
933
}
934
935
template <class charT>
936
inline typename std::enable_if<(sizeof(charT) > 1), const charT*>::type get_escape_R_string()
937
{
938
#ifdef BOOST_REGEX_MSVC
939
#  pragma warning(push)
940
#  pragma warning(disable:4309 4245)
941
#endif
942
   static const charT e1[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\x0D', '\x0A', '?',
943
      '|', '[', '\x0A', '\x0B', '\x0C', static_cast<charT>(0x85), static_cast<charT>(0x2028),
944
      static_cast<charT>(0x2029), ']', ')', ')', '\0' };
945
   static const charT e2[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\x0D', '\x0A', '?',
946
      '|', '[', '\x0A', '\x0B', '\x0C', static_cast<charT>(0x85), ']', ')', ')', '\0' };
947
948
   charT c = static_cast<charT>(0x2029u);
949
   bool b = (static_cast<unsigned>(c) == 0x2029u);
950
951
   return (b ? e1 : e2);
952
#ifdef BOOST_REGEX_MSVC
953
#  pragma warning(pop)
954
#endif
955
}
956
957
template <class charT>
958
inline typename std::enable_if<(sizeof(charT) == 1), const charT*>::type get_escape_R_string()
959
0
{
960
#ifdef BOOST_REGEX_MSVC
961
#  pragma warning(push)
962
#  pragma warning(disable:4309 4245)
963
#endif
964
0
   static const charT e2[] = { 
965
0
      static_cast<charT>('('), 
966
0
      static_cast<charT>('?'), 
967
0
      static_cast<charT>('-'), 
968
0
      static_cast<charT>('x'), 
969
0
      static_cast<charT>(':'), 
970
0
      static_cast<charT>('('), 
971
0
      static_cast<charT>('?'), 
972
0
      static_cast<charT>('>'), 
973
0
      static_cast<charT>('\x0D'), 
974
0
      static_cast<charT>('\x0A'), 
975
0
      static_cast<charT>('?'),
976
0
      static_cast<charT>('|'), 
977
0
      static_cast<charT>('['), 
978
0
      static_cast<charT>('\x0A'), 
979
0
      static_cast<charT>('\x0B'), 
980
0
      static_cast<charT>('\x0C'), 
981
0
      static_cast<charT>('\x85'), 
982
0
      static_cast<charT>(']'), 
983
0
      static_cast<charT>(')'), 
984
0
      static_cast<charT>(')'), 
985
0
      static_cast<charT>('\0') 
986
0
   };
987
0
   return e2;
988
#ifdef BOOST_REGEX_MSVC
989
#  pragma warning(pop)
990
#endif
991
0
}
992
993
} // BOOST_REGEX_DETAIL_NS
994
} // boost
995
996
#endif
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/regex_workaround.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 1998-2005
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         regex_workarounds.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares Misc workarounds.
17
  */
18
19
#ifndef BOOST_REGEX_WORKAROUND_HPP
20
#define BOOST_REGEX_WORKAROUND_HPP
21
22
#include <boost/regex/config.hpp>
23
#include <algorithm>
24
#include <stdexcept>
25
#include <cstring>
26
27
#ifndef BOOST_REGEX_STANDALONE
28
#include <boost/detail/workaround.hpp>
29
#include <boost/throw_exception.hpp>
30
#endif
31
32
#ifdef BOOST_REGEX_NO_BOOL
33
#  define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false)
34
#else
35
0
#  define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x)
36
#endif
37
38
/*****************************************************************************
39
 *
40
 *  helper functions pointer_construct/pointer_destroy:
41
 *
42
 ****************************************************************************/
43
44
#ifdef __cplusplus
45
namespace boost{ namespace BOOST_REGEX_DETAIL_NS{
46
47
#ifdef BOOST_REGEX_MSVC
48
#pragma warning (push)
49
#pragma warning (disable : 4100)
50
#endif
51
52
template <class T>
53
inline void pointer_destroy(T* p)
54
{ p->~T(); (void)p; }
55
56
#ifdef BOOST_REGEX_MSVC
57
#pragma warning (pop)
58
#endif
59
60
template <class T>
61
inline void pointer_construct(T* p, const T& t)
62
{ new (p) T(t); }
63
64
}} // namespaces
65
#endif
66
67
/*****************************************************************************
68
 *
69
 *  helper function copy:
70
 *
71
 ****************************************************************************/
72
73
#if defined(BOOST_WORKAROUND)
74
#if BOOST_WORKAROUND(BOOST_REGEX_MSVC, >= 1400) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__
75
#define BOOST_REGEX_HAS_STRCPY_S
76
#endif
77
#endif
78
79
#ifdef __cplusplus
80
namespace boost{ namespace BOOST_REGEX_DETAIL_NS{
81
82
#if defined(BOOST_REGEX_MSVC) && (BOOST_REGEX_MSVC < 1910)
83
   //
84
   // MSVC 10 will either emit warnings or else refuse to compile
85
   // code that makes perfectly legitimate use of std::copy, when
86
   // the OutputIterator type is a user-defined class (apparently all user 
87
   // defined iterators are "unsafe").  What's more Microsoft have removed their
88
   // non-standard "unchecked" versions, even though they are still in the MS
89
   // documentation!! Work around this as best we can: 
90
   //
91
   template<class InputIterator, class OutputIterator>
92
   inline OutputIterator copy(
93
      InputIterator first,
94
      InputIterator last,
95
      OutputIterator dest
96
   )
97
   {
98
      while (first != last)
99
         *dest++ = *first++;
100
      return dest;
101
   }
102
#else 
103
   using std::copy;
104
#endif 
105
106
107
#if defined(BOOST_REGEX_HAS_STRCPY_S)
108
109
   // use safe versions of strcpy etc:
110
   using ::strcpy_s;
111
   using ::strcat_s;
112
#else
113
   inline std::size_t strcpy_s(
114
      char *strDestination,
115
      std::size_t sizeInBytes,
116
      const char *strSource 
117
   )
118
0
   {
119
0
    std::size_t lenSourceWithNull = std::strlen(strSource) + 1;
120
0
    if (lenSourceWithNull > sizeInBytes)
121
0
         return 1;
122
0
    std::memcpy(strDestination, strSource, lenSourceWithNull);
123
0
      return 0;
124
0
   }
125
   inline std::size_t strcat_s(
126
      char *strDestination,
127
      std::size_t sizeInBytes,
128
      const char *strSource 
129
   )
130
0
   {
131
0
    std::size_t lenSourceWithNull = std::strlen(strSource) + 1;
132
0
    std::size_t lenDestination = std::strlen(strDestination);
133
0
    if (lenSourceWithNull + lenDestination > sizeInBytes)
134
0
         return 1;
135
0
    std::memcpy(strDestination + lenDestination, strSource, lenSourceWithNull);
136
0
      return 0;
137
0
   }
138
139
#endif
140
141
   inline void overflow_error_if_not_zero(std::size_t i)
142
0
   {
143
0
      if(i)
144
0
      {
145
0
         std::overflow_error e("String buffer too small");
146
0
#ifndef BOOST_REGEX_STANDALONE
147
0
         boost::throw_exception(e);
148
0
#else
149
0
         throw e;
150
0
#endif
151
0
      }
152
0
   }
153
154
}} // namespaces
155
156
#endif // __cplusplus
157
158
#endif // include guard
159
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/regex/v5/sub_match.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 1998-2002
4
 * John Maddock
5
 *
6
 * Use, modification and distribution are subject to the 
7
 * Boost Software License, Version 1.0. (See accompanying file 
8
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 *
10
 */
11
12
 /*
13
  *   LOCATION:    see http://www.boost.org for most recent version.
14
  *   FILE         sub_match.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares template class sub_match.
17
  */
18
19
#ifndef BOOST_REGEX_V5_SUB_MATCH_HPP
20
#define BOOST_REGEX_V5_SUB_MATCH_HPP
21
22
namespace boost{
23
24
template <class BidiIterator>
25
struct sub_match : public std::pair<BidiIterator, BidiIterator>
26
{
27
   typedef typename std::iterator_traits<BidiIterator>::value_type       value_type;
28
   typedef typename std::iterator_traits<BidiIterator>::difference_type  difference_type;
29
   typedef          BidiIterator                                                     iterator_type;
30
   typedef          BidiIterator                                                     iterator;
31
   typedef          BidiIterator                                                     const_iterator;
32
33
   bool matched;
34
35
5
   sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}
36
5
   sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}
37
   template <class T, class A>
38
   operator std::basic_string<value_type, T, A> ()const
39
   {
40
      return matched ? std::basic_string<value_type, T, A>(this->first, this->second) : std::basic_string<value_type, T, A>();
41
   }
42
   difference_type  length()const
43
   {
44
      difference_type n = matched ? std::distance((BidiIterator)this->first, (BidiIterator)this->second) : 0;
45
      return n;
46
   }
47
   std::basic_string<value_type> str()const
48
   {
49
      std::basic_string<value_type> result;
50
      if(matched)
51
      {
52
         std::size_t len = std::distance((BidiIterator)this->first, (BidiIterator)this->second);
53
         result.reserve(len);
54
         BidiIterator i = this->first;
55
         while(i != this->second)
56
         {
57
            result.append(1, *i);
58
            ++i;
59
         }
60
      }
61
      return result;
62
   }
63
   int compare(const sub_match& s)const
64
   {
65
      if(matched != s.matched)
66
         return static_cast<int>(matched) - static_cast<int>(s.matched);
67
      return str().compare(s.str());
68
   }
69
   int compare(const std::basic_string<value_type>& s)const
70
   {
71
      return str().compare(s);
72
   }
73
   int compare(const value_type* p)const
74
   {
75
      return str().compare(p);
76
   }
77
78
   bool operator==(const sub_match& that)const
79
   { return compare(that) == 0; }
80
   bool  operator !=(const sub_match& that)const
81
   { return compare(that) != 0; }
82
   bool operator<(const sub_match& that)const
83
   { return compare(that) < 0; }
84
   bool operator>(const sub_match& that)const
85
   { return compare(that) > 0; }
86
   bool operator<=(const sub_match& that)const
87
   { return compare(that) <= 0; }
88
   bool operator>=(const sub_match& that)const
89
   { return compare(that) >= 0; }
90
91
#ifdef BOOST_REGEX_MATCH_EXTRA
92
   typedef std::vector<sub_match<BidiIterator> > capture_sequence_type;
93
94
   const capture_sequence_type& captures()const
95
   {
96
      if(!m_captures) 
97
         m_captures.reset(new capture_sequence_type());
98
      return *m_captures;
99
   }
100
   //
101
   // Private implementation API: DO NOT USE!
102
   //
103
   capture_sequence_type& get_captures()const
104
   {
105
      if(!m_captures) 
106
         m_captures.reset(new capture_sequence_type());
107
      return *m_captures;
108
   }
109
110
private:
111
   mutable std::unique_ptr<capture_sequence_type> m_captures;
112
public:
113
114
#endif
115
   sub_match(const sub_match& that, bool 
116
#ifdef BOOST_REGEX_MATCH_EXTRA
117
      deep_copy
118
#endif
119
      = true
120
      ) 
121
      : std::pair<BidiIterator, BidiIterator>(that), 
122
        matched(that.matched) 
123
35
   {
124
#ifdef BOOST_REGEX_MATCH_EXTRA
125
      if(that.m_captures)
126
         if(deep_copy)
127
            m_captures.reset(new capture_sequence_type(*(that.m_captures)));
128
#endif
129
35
   }
130
   sub_match& operator=(const sub_match& that)
131
0
   {
132
0
      this->first = that.first;
133
0
      this->second = that.second;
134
0
      matched = that.matched;
135
#ifdef BOOST_REGEX_MATCH_EXTRA
136
      if(that.m_captures)
137
         get_captures() = *(that.m_captures);
138
#endif
139
0
      return *this;
140
0
   }
141
   //
142
   // Make this type a range, for both Boost.Range, and C++11:
143
   //
144
   BidiIterator begin()const { return this->first; }
145
   BidiIterator end()const { return this->second; }
146
};
147
148
typedef sub_match<const char*> csub_match;
149
typedef sub_match<std::string::const_iterator> ssub_match;
150
#ifndef BOOST_NO_WREGEX
151
typedef sub_match<const wchar_t*> wcsub_match;
152
typedef sub_match<std::wstring::const_iterator> wssub_match;
153
#endif
154
155
// comparison to std::basic_string<> part 1:
156
template <class RandomAccessIterator, class traits, class Allocator>
157
inline bool operator == (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
158
                  const sub_match<RandomAccessIterator>& m)
159
{ return s.compare(m.str()) == 0; }
160
template <class RandomAccessIterator, class traits, class Allocator>
161
inline bool operator != (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
162
                  const sub_match<RandomAccessIterator>& m)
163
{ return s.compare(m.str()) != 0; }
164
template <class RandomAccessIterator, class traits, class Allocator>
165
inline bool operator < (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
166
                 const sub_match<RandomAccessIterator>& m)
167
{ return s.compare(m.str()) < 0; }
168
template <class RandomAccessIterator, class traits, class Allocator>
169
inline bool operator <= (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
170
                  const sub_match<RandomAccessIterator>& m)
171
{ return s.compare(m.str()) <= 0; }
172
template <class RandomAccessIterator, class traits, class Allocator>
173
inline bool operator >= (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
174
                  const sub_match<RandomAccessIterator>& m)
175
{ return s.compare(m.str()) >= 0; }
176
template <class RandomAccessIterator, class traits, class Allocator>
177
inline bool operator > (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
178
                 const sub_match<RandomAccessIterator>& m)
179
{ return s.compare(m.str()) > 0; }
180
// comparison to std::basic_string<> part 2:
181
template <class RandomAccessIterator, class traits, class Allocator>
182
inline bool operator == (const sub_match<RandomAccessIterator>& m,
183
                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
184
{ return m.str().compare(s) == 0; }
185
template <class RandomAccessIterator, class traits, class Allocator>
186
inline bool operator != (const sub_match<RandomAccessIterator>& m,
187
                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
188
{ return m.str().compare(s) != 0; }
189
template <class RandomAccessIterator, class traits, class Allocator>
190
inline bool operator < (const sub_match<RandomAccessIterator>& m,
191
                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
192
{ return m.str().compare(s) < 0; }
193
template <class RandomAccessIterator, class traits, class Allocator>
194
inline bool operator > (const sub_match<RandomAccessIterator>& m,
195
                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
196
{ return m.str().compare(s) > 0; }
197
template <class RandomAccessIterator, class traits, class Allocator>
198
inline bool operator <= (const sub_match<RandomAccessIterator>& m,
199
                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
200
{ return m.str().compare(s) <= 0; }
201
template <class RandomAccessIterator, class traits, class Allocator>
202
inline bool operator >= (const sub_match<RandomAccessIterator>& m,
203
                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
204
{ return m.str().compare(s) >= 0; }
205
// comparison to const charT* part 1:
206
template <class RandomAccessIterator>
207
inline bool operator == (const sub_match<RandomAccessIterator>& m,
208
                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
209
{ return m.str().compare(s) == 0; }
210
template <class RandomAccessIterator>
211
inline bool operator != (const sub_match<RandomAccessIterator>& m,
212
                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
213
{ return m.str().compare(s) != 0; }
214
template <class RandomAccessIterator>
215
inline bool operator > (const sub_match<RandomAccessIterator>& m,
216
                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
217
{ return m.str().compare(s) > 0; }
218
template <class RandomAccessIterator>
219
inline bool operator < (const sub_match<RandomAccessIterator>& m,
220
                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
221
{ return m.str().compare(s) < 0; }
222
template <class RandomAccessIterator>
223
inline bool operator >= (const sub_match<RandomAccessIterator>& m,
224
                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
225
{ return m.str().compare(s) >= 0; }
226
template <class RandomAccessIterator>
227
inline bool operator <= (const sub_match<RandomAccessIterator>& m,
228
                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
229
{ return m.str().compare(s) <= 0; }
230
// comparison to const charT* part 2:
231
template <class RandomAccessIterator>
232
inline bool operator == (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
233
                  const sub_match<RandomAccessIterator>& m)
234
{ return m.str().compare(s) == 0; }
235
template <class RandomAccessIterator>
236
inline bool operator != (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
237
                  const sub_match<RandomAccessIterator>& m)
238
{ return m.str().compare(s) != 0; }
239
template <class RandomAccessIterator>
240
inline bool operator < (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
241
                  const sub_match<RandomAccessIterator>& m)
242
{ return m.str().compare(s) > 0; }
243
template <class RandomAccessIterator>
244
inline bool operator > (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
245
                  const sub_match<RandomAccessIterator>& m)
246
{ return m.str().compare(s) < 0; }
247
template <class RandomAccessIterator>
248
inline bool operator <= (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
249
                  const sub_match<RandomAccessIterator>& m)
250
{ return m.str().compare(s) >= 0; }
251
template <class RandomAccessIterator>
252
inline bool operator >= (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
253
                  const sub_match<RandomAccessIterator>& m)
254
{ return m.str().compare(s) <= 0; }
255
256
// comparison to const charT& part 1:
257
template <class RandomAccessIterator>
258
inline bool operator == (const sub_match<RandomAccessIterator>& m,
259
                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
260
{ return m.str().compare(0, m.length(), &s, 1) == 0; }
261
template <class RandomAccessIterator>
262
inline bool operator != (const sub_match<RandomAccessIterator>& m,
263
                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
264
{ return m.str().compare(0, m.length(), &s, 1) != 0; }
265
template <class RandomAccessIterator>
266
inline bool operator > (const sub_match<RandomAccessIterator>& m,
267
                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
268
{ return m.str().compare(0, m.length(), &s, 1) > 0; }
269
template <class RandomAccessIterator>
270
inline bool operator < (const sub_match<RandomAccessIterator>& m,
271
                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
272
{ return m.str().compare(0, m.length(), &s, 1) < 0; }
273
template <class RandomAccessIterator>
274
inline bool operator >= (const sub_match<RandomAccessIterator>& m,
275
                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
276
{ return m.str().compare(0, m.length(), &s, 1) >= 0; }
277
template <class RandomAccessIterator>
278
inline bool operator <= (const sub_match<RandomAccessIterator>& m,
279
                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
280
{ return m.str().compare(0, m.length(), &s, 1) <= 0; }
281
// comparison to const charT* part 2:
282
template <class RandomAccessIterator>
283
inline bool operator == (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
284
                  const sub_match<RandomAccessIterator>& m)
285
{ return m.str().compare(0, m.length(), &s, 1) == 0; }
286
template <class RandomAccessIterator>
287
inline bool operator != (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
288
                  const sub_match<RandomAccessIterator>& m)
289
{ return m.str().compare(0, m.length(), &s, 1) != 0; }
290
template <class RandomAccessIterator>
291
inline bool operator < (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
292
                  const sub_match<RandomAccessIterator>& m)
293
{ return m.str().compare(0, m.length(), &s, 1) > 0; }
294
template <class RandomAccessIterator>
295
inline bool operator > (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
296
                  const sub_match<RandomAccessIterator>& m)
297
{ return m.str().compare(0, m.length(), &s, 1) < 0; }
298
template <class RandomAccessIterator>
299
inline bool operator <= (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
300
                  const sub_match<RandomAccessIterator>& m)
301
{ return m.str().compare(0, m.length(), &s, 1) >= 0; }
302
template <class RandomAccessIterator>
303
inline bool operator >= (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
304
                  const sub_match<RandomAccessIterator>& m)
305
{ return m.str().compare(0, m.length(), &s, 1) <= 0; }
306
307
// addition operators:
308
template <class RandomAccessIterator, class traits, class Allocator>
309
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> 
310
operator + (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
311
                  const sub_match<RandomAccessIterator>& m)
312
{
313
   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
314
   result.reserve(s.size() + m.length() + 1);
315
   return result.append(s).append(m.first, m.second);
316
}
317
template <class RandomAccessIterator, class traits, class Allocator>
318
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> 
319
operator + (const sub_match<RandomAccessIterator>& m,
320
            const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
321
{
322
   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
323
   result.reserve(s.size() + m.length() + 1);
324
   return result.append(m.first, m.second).append(s);
325
}
326
template <class RandomAccessIterator>
327
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> 
328
operator + (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
329
                  const sub_match<RandomAccessIterator>& m)
330
{
331
   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
332
   result.reserve(std::char_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
333
   return result.append(s).append(m.first, m.second);
334
}
335
template <class RandomAccessIterator>
336
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> 
337
operator + (const sub_match<RandomAccessIterator>& m,
338
            typename std::iterator_traits<RandomAccessIterator>::value_type const * s)
339
{
340
   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
341
   result.reserve(std::char_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
342
   return result.append(m.first, m.second).append(s);
343
}
344
template <class RandomAccessIterator>
345
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> 
346
operator + (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
347
                  const sub_match<RandomAccessIterator>& m)
348
{
349
   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
350
   result.reserve(m.length() + 2);
351
   return result.append(1, s).append(m.first, m.second);
352
}
353
template <class RandomAccessIterator>
354
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> 
355
operator + (const sub_match<RandomAccessIterator>& m,
356
            typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
357
{
358
   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
359
   result.reserve(m.length() + 2);
360
   return result.append(m.first, m.second).append(1, s);
361
}
362
template <class RandomAccessIterator>
363
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> 
364
operator + (const sub_match<RandomAccessIterator>& m1,
365
            const sub_match<RandomAccessIterator>& m2)
366
{
367
   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
368
   result.reserve(m1.length() + m2.length() + 1);
369
   return result.append(m1.first, m1.second).append(m2.first, m2.second);
370
}
371
template <class charT, class traits, class RandomAccessIterator>
372
std::basic_ostream<charT, traits>&
373
   operator << (std::basic_ostream<charT, traits>& os,
374
                const sub_match<RandomAccessIterator>& s)
375
{
376
   return (os << s.str());
377
}
378
379
} // namespace boost
380
381
#endif
382
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/static_assert.hpp
Line
Count
Source
1
//  (C) Copyright John Maddock 2000.
2
//  Use, modification and distribution are subject to the 
3
//  Boost Software License, Version 1.0. (See accompanying file 
4
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6
//  See http://www.boost.org/libs/static_assert for documentation.
7
8
/*
9
 Revision history:
10
   02 August 2000
11
      Initial version.
12
*/
13
14
#ifndef BOOST_STATIC_ASSERT_HPP
15
#define BOOST_STATIC_ASSERT_HPP
16
17
#include <boost/config.hpp>
18
#include <boost/detail/workaround.hpp>
19
20
#if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
21
//
22
// This is horrible, but it seems to be the only we can shut up the
23
// "anonymous variadic macros were introduced in C99 [-Wvariadic-macros]"
24
// warning that get spewed out otherwise in non-C++11 mode.
25
//
26
#pragma GCC system_header
27
#endif
28
29
#ifndef BOOST_NO_CXX11_STATIC_ASSERT
30
#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
31
#     define BOOST_STATIC_ASSERT_MSG( ... ) static_assert(__VA_ARGS__)
32
#  else
33
#     define BOOST_STATIC_ASSERT_MSG( B, Msg ) static_assert( B, Msg )
34
#  endif
35
#else
36
#     define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B )
37
#endif
38
39
#ifdef BOOST_BORLANDC
40
//
41
// workaround for buggy integral-constant expression support:
42
#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS
43
#endif
44
45
#if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4))
46
// gcc 3.3 and 3.4 don't produce good error messages with the default version:
47
#  define BOOST_SA_GCC_WORKAROUND
48
#endif
49
50
//
51
// If the compiler issues warnings about old C style casts,
52
// then enable this:
53
//
54
#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))
55
#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
56
#     define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) ((__VA_ARGS__) != 0)
57
#  else
58
#     define BOOST_STATIC_ASSERT_BOOL_CAST( x ) ((x) != 0)
59
#  endif
60
#else
61
#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
62
#     define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) (bool)(__VA_ARGS__)
63
#  else
64
#     define BOOST_STATIC_ASSERT_BOOL_CAST(x) (bool)(x)
65
#  endif
66
#endif
67
68
#ifndef BOOST_NO_CXX11_STATIC_ASSERT
69
#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
70
149
#     define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__)
71
#  else
72
#     define BOOST_STATIC_ASSERT( B ) static_assert(B, #B)
73
#  endif
74
#else
75
76
namespace boost{
77
78
// HP aCC cannot deal with missing names for template value parameters
79
template <bool x> struct STATIC_ASSERTION_FAILURE;
80
81
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
82
83
// HP aCC cannot deal with missing names for template value parameters
84
template<int x> struct static_assert_test{};
85
86
}
87
88
//
89
// Implicit instantiation requires that all member declarations be
90
// instantiated, but that the definitions are *not* instantiated.
91
//
92
// It's not particularly clear how this applies to enum's or typedefs;
93
// both are described as declarations [7.1.3] and [7.2] in the standard,
94
// however some compilers use "delayed evaluation" of one or more of
95
// these when implicitly instantiating templates.  We use typedef declarations
96
// by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum
97
// version gets better results from your compiler...
98
//
99
// Implementation:
100
// Both of these versions rely on sizeof(incomplete_type) generating an error
101
// message containing the name of the incomplete type.  We use
102
// "STATIC_ASSERTION_FAILURE" as the type name here to generate
103
// an eye catching error message.  The result of the sizeof expression is either
104
// used as an enum initialiser, or as a template argument depending which version
105
// is in use...
106
// Note that the argument to the assert is explicitly cast to bool using old-
107
// style casts: too many compilers currently have problems with static_cast
108
// when used inside integral constant expressions.
109
//
110
#if !defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS)
111
112
#if defined(BOOST_MSVC) && defined(BOOST_NO_CXX11_VARIADIC_MACROS)
113
#define BOOST_STATIC_ASSERT( B ) \
114
   typedef ::boost::static_assert_test<\
115
      sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\
116
         BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__)
117
#elif defined(BOOST_MSVC)
118
#define BOOST_STATIC_ASSERT(...) \
119
   typedef ::boost::static_assert_test<\
120
      sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST (__VA_ARGS__) >)>\
121
         BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__)
122
#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND))  && defined(BOOST_NO_CXX11_VARIADIC_MACROS)
123
// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error 
124
// instead of warning in case of failure
125
# define BOOST_STATIC_ASSERT( B ) \
126
    typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \
127
        [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >::value ]
128
#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND))  && !defined(BOOST_NO_CXX11_VARIADIC_MACROS)
129
// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error 
130
// instead of warning in case of failure
131
# define BOOST_STATIC_ASSERT(...) \
132
    typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \
133
        [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >::value ]
134
#elif defined(__sgi)
135
// special version for SGI MIPSpro compiler
136
#define BOOST_STATIC_ASSERT( B ) \
137
   BOOST_STATIC_CONSTANT(bool, \
138
     BOOST_JOIN(boost_static_assert_test_, __LINE__) = ( B )); \
139
   typedef ::boost::static_assert_test<\
140
     sizeof(::boost::STATIC_ASSERTION_FAILURE< \
141
       BOOST_JOIN(boost_static_assert_test_, __LINE__) >)>\
142
         BOOST_JOIN(boost_static_assert_typedef_, __LINE__)
143
#elif BOOST_WORKAROUND(__MWERKS__, <= 0x3003)
144
// special version for CodeWarrior <= 8.x
145
#define BOOST_STATIC_ASSERT( B ) \
146
   BOOST_STATIC_CONSTANT(int, \
147
     BOOST_JOIN(boost_static_assert_test_, __LINE__) = \
148
       sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >) )
149
#else
150
// generic version
151
#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
152
#     define BOOST_STATIC_ASSERT( ... ) \
153
         typedef ::boost::static_assert_test<\
154
            sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\
155
               BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED
156
#  else
157
#     define BOOST_STATIC_ASSERT( B ) \
158
         typedef ::boost::static_assert_test<\
159
            sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >)>\
160
               BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED
161
#  endif
162
#endif
163
164
#else
165
// alternative enum based implementation:
166
#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
167
#    define BOOST_STATIC_ASSERT( ... ) \
168
         enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \
169
            = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( __VA_ARGS__ ) >) }
170
#  else
171
#    define BOOST_STATIC_ASSERT(B) \
172
         enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \
173
            = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) }
174
#  endif
175
#endif
176
#endif // defined(BOOST_NO_CXX11_STATIC_ASSERT)
177
178
#endif // BOOST_STATIC_ASSERT_HPP
179
180
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/throw_exception.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
2
#define BOOST_THROW_EXCEPTION_HPP_INCLUDED
3
4
// MS compatible compilers support #pragma once
5
6
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
7
# pragma once
8
#endif
9
10
//
11
//  boost/throw_exception.hpp
12
//
13
//  Copyright (c) 2002, 2018, 2019 Peter Dimov
14
//  Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc.
15
//
16
//  Distributed under the Boost Software License, Version 1.0. (See
17
//  accompanying file LICENSE_1_0.txt or copy at
18
//  http://www.boost.org/LICENSE_1_0.txt)
19
//
20
//  http://www.boost.org/libs/throw_exception
21
//
22
23
#include <boost/exception/exception.hpp>
24
#include <boost/assert/source_location.hpp>
25
#include <boost/config.hpp>
26
#include <boost/config/workaround.hpp>
27
#include <exception>
28
29
#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) )
30
# define BOOST_EXCEPTION_DISABLE
31
#endif
32
33
namespace boost
34
{
35
36
#if defined( BOOST_NO_EXCEPTIONS )
37
38
BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined
39
BOOST_NORETURN void throw_exception( std::exception const & e, boost::source_location const & loc ); // user defined
40
41
#endif
42
43
// boost::wrapexcept<E>
44
45
namespace detail
46
{
47
48
typedef char (&wrapexcept_s1)[ 1 ];
49
typedef char (&wrapexcept_s2)[ 2 ];
50
51
template<class T> wrapexcept_s1 wrapexcept_is_convertible( T* );
52
template<class T> wrapexcept_s2 wrapexcept_is_convertible( void* );
53
54
template<class E, class B, int I = sizeof( wrapexcept_is_convertible<B>( static_cast< E* >( 0 ) ) ) > struct wrapexcept_add_base;
55
56
template<class E, class B> struct wrapexcept_add_base<E, B, 1>
57
{
58
    struct type {};
59
};
60
61
template<class E, class B> struct wrapexcept_add_base<E, B, 2>
62
{
63
    typedef B type;
64
};
65
66
} // namespace detail
67
68
template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept:
69
    public detail::wrapexcept_add_base<E, boost::exception_detail::clone_base>::type,
70
    public E,
71
    public detail::wrapexcept_add_base<E, boost::exception>::type
72
{
73
private:
74
75
    struct deleter
76
    {
77
        wrapexcept * p_;
78
0
        ~deleter() { delete p_; }
Unexecuted instantiation: _ZN5boost10wrapexceptISt13runtime_errorE7deleterD2Ev
Unexecuted instantiation: _ZN5boost10wrapexceptINS_11regex_errorEE7deleterD2Ev
Unexecuted instantiation: _ZN5boost10wrapexceptISt16invalid_argumentE7deleterD2Ev
Unexecuted instantiation: _ZN5boost10wrapexceptISt11logic_errorE7deleterD2Ev
Unexecuted instantiation: _ZN5boost10wrapexceptINS_17bad_function_callEE7deleterD2Ev
79
    };
80
81
private:
82
83
    void copy_from( void const* )
84
0
    {
85
0
    }
Unexecuted instantiation: _ZN5boost10wrapexceptISt13runtime_errorE9copy_fromEPKv
Unexecuted instantiation: _ZN5boost10wrapexceptINS_11regex_errorEE9copy_fromEPKv
Unexecuted instantiation: _ZN5boost10wrapexceptISt16invalid_argumentE9copy_fromEPKv
Unexecuted instantiation: _ZN5boost10wrapexceptISt11logic_errorE9copy_fromEPKv
Unexecuted instantiation: _ZN5boost10wrapexceptINS_17bad_function_callEE9copy_fromEPKv
Unexecuted instantiation: _ZN5boost10wrapexceptISt14overflow_errorE9copy_fromEPKv
86
87
    void copy_from( boost::exception const* p )
88
    {
89
        static_cast<boost::exception&>( *this ) = *p;
90
    }
91
92
public:
93
94
    explicit wrapexcept( E const & e ): E( e )
95
0
    {
96
0
        copy_from( &e );
97
0
    }
Unexecuted instantiation: _ZN5boost10wrapexceptISt13runtime_errorEC2ERKS1_
Unexecuted instantiation: _ZN5boost10wrapexceptINS_11regex_errorEEC2ERKS1_
Unexecuted instantiation: _ZN5boost10wrapexceptISt16invalid_argumentEC2ERKS1_
Unexecuted instantiation: _ZN5boost10wrapexceptISt11logic_errorEC2ERKS1_
Unexecuted instantiation: _ZN5boost10wrapexceptINS_17bad_function_callEEC2ERKS1_
98
99
    explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e )
100
    {
101
        copy_from( &e );
102
103
        set_info( *this, throw_file( loc.file_name() ) );
104
        set_info( *this, throw_line( loc.line() ) );
105
        set_info( *this, throw_function( loc.function_name() ) );
106
    }
107
108
    virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE
109
0
    {
110
0
        wrapexcept * p = new wrapexcept( *this );
111
0
        deleter del = { p };
112
113
0
        boost::exception_detail::copy_boost_exception( p, this );
114
115
0
        del.p_ = 0;
116
0
        return p;
117
0
    }
Unexecuted instantiation: _ZNK5boost10wrapexceptISt13runtime_errorE5cloneEv
Unexecuted instantiation: _ZNK5boost10wrapexceptINS_11regex_errorEE5cloneEv
Unexecuted instantiation: _ZNK5boost10wrapexceptISt16invalid_argumentE5cloneEv
Unexecuted instantiation: _ZNK5boost10wrapexceptISt11logic_errorE5cloneEv
Unexecuted instantiation: _ZNK5boost10wrapexceptINS_17bad_function_callEE5cloneEv
Unexecuted instantiation: _ZNK5boost10wrapexceptISt14overflow_errorE5cloneEv
118
119
    virtual void rethrow() const BOOST_OVERRIDE
120
0
    {
121
#if defined( BOOST_NO_EXCEPTIONS )
122
123
        boost::throw_exception( *this );
124
125
#else
126
127
0
        throw *this;
128
129
0
#endif
130
0
    }
Unexecuted instantiation: _ZNK5boost10wrapexceptISt13runtime_errorE7rethrowEv
Unexecuted instantiation: _ZNK5boost10wrapexceptINS_11regex_errorEE7rethrowEv
Unexecuted instantiation: _ZNK5boost10wrapexceptISt16invalid_argumentE7rethrowEv
Unexecuted instantiation: _ZNK5boost10wrapexceptISt11logic_errorE7rethrowEv
Unexecuted instantiation: _ZNK5boost10wrapexceptINS_17bad_function_callEE7rethrowEv
Unexecuted instantiation: _ZNK5boost10wrapexceptISt14overflow_errorE7rethrowEv
131
};
132
133
// All boost exceptions are required to derive from std::exception,
134
// to ensure compatibility with BOOST_NO_EXCEPTIONS.
135
136
0
inline void throw_exception_assert_compatibility( std::exception const & ) {}
137
138
// boost::throw_exception
139
140
#if !defined( BOOST_NO_EXCEPTIONS )
141
142
#if defined( BOOST_EXCEPTION_DISABLE )
143
144
template<class E> BOOST_NORETURN void throw_exception( E const & e )
145
{
146
    throw_exception_assert_compatibility( e );
147
    throw e;
148
}
149
150
template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & )
151
{
152
    throw_exception_assert_compatibility( e );
153
    throw e;
154
}
155
156
#else // defined( BOOST_EXCEPTION_DISABLE )
157
158
template<class E> BOOST_NORETURN void throw_exception( E const & e )
159
0
{
160
0
    throw_exception_assert_compatibility( e );
161
0
    throw wrapexcept<E>( e );
162
0
}
Unexecuted instantiation: _ZN5boost15throw_exceptionISt13runtime_errorEEvRKT_
Unexecuted instantiation: _ZN5boost15throw_exceptionINS_11regex_errorEEEvRKT_
Unexecuted instantiation: _ZN5boost15throw_exceptionISt16invalid_argumentEEvRKT_
Unexecuted instantiation: _ZN5boost15throw_exceptionISt11logic_errorEEvRKT_
Unexecuted instantiation: _ZN5boost15throw_exceptionINS_17bad_function_callEEEvRKT_
Unexecuted instantiation: _ZN5boost15throw_exceptionISt14overflow_errorEEvRKT_
163
164
template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & loc )
165
{
166
    throw_exception_assert_compatibility( e );
167
    throw wrapexcept<E>( e, loc );
168
}
169
170
#endif // defined( BOOST_EXCEPTION_DISABLE )
171
172
#endif // !defined( BOOST_NO_EXCEPTIONS )
173
174
} // namespace boost
175
176
// BOOST_THROW_EXCEPTION
177
178
#define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
179
180
#endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/tuple/detail/tuple_basic.hpp
Line
Count
Source (jump to first uncovered line)
1
//  tuple_basic.hpp -----------------------------------------------------
2
3
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
4
//
5
// Distributed under the Boost Software License, Version 1.0. (See
6
// accompanying file LICENSE_1_0.txt or copy at
7
// http://www.boost.org/LICENSE_1_0.txt)
8
9
// For more information, see http://www.boost.org
10
11
// Outside help:
12
// This and that, Gary Powell.
13
// Fixed return types for get_head/get_tail
14
// ( and other bugs ) per suggestion of Jens Maurer
15
// simplified element type accessors + bug fix  (Jeremy Siek)
16
// Several changes/additions according to suggestions by Douglas Gregor,
17
// William Kempf, Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes,
18
// David Abrahams.
19
20
// Revision history:
21
// 2002 05 01 Hugo Duncan: Fix for Borland after Jaakko's previous changes
22
// 2002 04 18 Jaakko: tuple element types can be void or plain function
23
//                    types, as long as no object is created.
24
//                    Tuple objects can no hold even noncopyable types
25
//                    such as arrays.
26
// 2001 10 22 John Maddock
27
//      Fixes for Borland C++
28
// 2001 08 30 David Abrahams
29
//      Added default constructor for cons<>.
30
// -----------------------------------------------------------------
31
32
#ifndef BOOST_TUPLE_BASIC_HPP
33
#define BOOST_TUPLE_BASIC_HPP
34
35
36
#include <utility> // needed for the assignment from pair to tuple
37
38
#include <boost/type_traits/cv_traits.hpp>
39
#include <boost/type_traits/function_traits.hpp>
40
#include <boost/type_traits/integral_constant.hpp>
41
#include <boost/utility/swap.hpp>
42
43
#include <boost/detail/workaround.hpp> // needed for BOOST_WORKAROUND
44
45
#if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
46
#pragma GCC diagnostic push
47
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
48
#endif
49
50
namespace boost {
51
namespace tuples {
52
53
// -- null_type --------------------------------------------------------
54
struct null_type {};
55
56
// a helper function to provide a const null_type type temporary
57
namespace detail {
58
0
  inline const null_type cnull() { return null_type(); }
59
60
61
// -- if construct ------------------------------------------------
62
// Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
63
64
template <bool If, class Then, class Else> struct IF { typedef Then RET; };
65
66
template <class Then, class Else> struct IF<false, Then, Else> {
67
  typedef Else RET;
68
};
69
70
} // end detail
71
72
// - cons forward declaration -----------------------------------------------
73
template <class HT, class TT> struct cons;
74
75
76
// - tuple forward declaration -----------------------------------------------
77
template <
78
  class T0 = null_type, class T1 = null_type, class T2 = null_type,
79
  class T3 = null_type, class T4 = null_type, class T5 = null_type,
80
  class T6 = null_type, class T7 = null_type, class T8 = null_type,
81
  class T9 = null_type>
82
class tuple;
83
84
// tuple_length forward declaration
85
template<class T> struct length;
86
87
88
89
namespace detail {
90
91
// -- generate error template, referencing to non-existing members of this
92
// template is used to produce compilation errors intentionally
93
template<class T>
94
class generate_error;
95
96
template<int N>
97
struct drop_front {
98
    template<class Tuple>
99
    struct apply {
100
        typedef BOOST_DEDUCED_TYPENAME drop_front<N-1>::BOOST_NESTED_TEMPLATE
101
            apply<Tuple> next;
102
        typedef BOOST_DEDUCED_TYPENAME next::type::tail_type type;
103
        static const type& call(const Tuple& tup) {
104
            return next::call(tup).tail;
105
        }
106
    };
107
};
108
109
template<>
110
struct drop_front<0> {
111
    template<class Tuple>
112
    struct apply {
113
        typedef Tuple type;
114
        static const type& call(const Tuple& tup) {
115
            return tup;
116
        }
117
    };
118
};
119
120
} // end of namespace detail
121
122
123
// -cons type accessors ----------------------------------------
124
// typename tuples::element<N,T>::type gets the type of the
125
// Nth element ot T, first element is at index 0
126
// -------------------------------------------------------
127
128
#ifndef BOOST_NO_CV_SPECIALIZATIONS
129
130
template<int N, class T>
131
struct element
132
{
133
  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
134
      apply<T>::type::head_type type;
135
};
136
137
template<int N, class T>
138
struct element<N, const T>
139
{
140
private:
141
  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
142
      apply<T>::type::head_type unqualified_type;
143
public:
144
#if BOOST_WORKAROUND(BOOST_BORLANDC,<0x600)
145
  typedef const unqualified_type type;
146
#else
147
  typedef BOOST_DEDUCED_TYPENAME boost::add_const<unqualified_type>::type type;
148
#endif
149
};
150
#else // def BOOST_NO_CV_SPECIALIZATIONS
151
152
namespace detail {
153
154
template<int N, class T, bool IsConst>
155
struct element_impl
156
{
157
  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
158
      apply<T>::type::head_type type;
159
};
160
161
template<int N, class T>
162
struct element_impl<N, T, true /* IsConst */>
163
{
164
  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
165
      apply<T>::type::head_type unqualified_type;
166
  typedef const unqualified_type type;
167
};
168
169
} // end of namespace detail
170
171
172
template<int N, class T>
173
struct element:
174
  public detail::element_impl<N, T, ::boost::is_const<T>::value>
175
{
176
};
177
178
#endif
179
180
181
// -get function templates -----------------------------------------------
182
// Usage: get<N>(aTuple)
183
184
// -- some traits classes for get functions
185
186
// access traits lifted from detail namespace to be part of the interface,
187
// (Joel de Guzman's suggestion). Rationale: get functions are part of the
188
// interface, so should the way to express their return types be.
189
190
template <class T> struct access_traits {
191
  typedef const T& const_type;
192
  typedef T& non_const_type;
193
194
  typedef const typename boost::remove_cv<T>::type& parameter_type;
195
196
// used as the tuple constructors parameter types
197
// Rationale: non-reference tuple element types can be cv-qualified.
198
// It should be possible to initialize such types with temporaries,
199
// and when binding temporaries to references, the reference must
200
// be non-volatile and const. 8.5.3. (5)
201
};
202
203
template <class T> struct access_traits<T&> {
204
205
  typedef T& const_type;
206
  typedef T& non_const_type;
207
208
  typedef T& parameter_type;
209
};
210
211
// get function for non-const cons-lists, returns a reference to the element
212
213
template<int N, class HT, class TT>
214
inline typename access_traits<
215
                  typename element<N, cons<HT, TT> >::type
216
                >::non_const_type
217
get(cons<HT, TT>& c) {
218
  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
219
      apply<cons<HT, TT> > impl;
220
  typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
221
  return const_cast<cons_element&>(impl::call(c)).head;
222
}
223
224
// get function for const cons-lists, returns a const reference to
225
// the element. If the element is a reference, returns the reference
226
// as such (that is, can return a non-const reference)
227
template<int N, class HT, class TT>
228
inline typename access_traits<
229
                  typename element<N, cons<HT, TT> >::type
230
                >::const_type
231
get(const cons<HT, TT>& c) {
232
  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
233
      apply<cons<HT, TT> > impl;
234
  return impl::call(c).head;
235
}
236
237
// -- the cons template  --------------------------------------------------
238
namespace detail {
239
240
//  These helper templates wrap void types and plain function types.
241
//  The reationale is to allow one to write tuple types with those types
242
//  as elements, even though it is not possible to instantiate such object.
243
//  E.g: typedef tuple<void> some_type; // ok
244
//  but: some_type x; // fails
245
246
template <class T> class non_storeable_type {
247
  non_storeable_type();
248
};
249
250
template <class T> struct wrap_non_storeable_type {
251
  typedef typename IF<
252
    ::boost::is_function<T>::value, non_storeable_type<T>, T
253
  >::RET type;
254
};
255
template <> struct wrap_non_storeable_type<void> {
256
  typedef non_storeable_type<void> type;
257
};
258
259
} // detail
260
261
template <class HT, class TT>
262
struct cons {
263
264
  typedef HT head_type;
265
  typedef TT tail_type;
266
267
  typedef typename
268
    detail::wrap_non_storeable_type<head_type>::type stored_head_type;
269
270
  stored_head_type head;
271
  tail_type tail;
272
273
  typename access_traits<stored_head_type>::non_const_type
274
  get_head() { return head; }
275
276
  typename access_traits<tail_type>::non_const_type
277
  get_tail() { return tail; }
278
279
  typename access_traits<stored_head_type>::const_type
280
  get_head() const { return head; }
281
282
  typename access_traits<tail_type>::const_type
283
  get_tail() const { return tail; }
284
285
  cons() : head(), tail() {}
286
  //  cons() : head(detail::default_arg<HT>::f()), tail() {}
287
288
  // the argument for head is not strictly needed, but it prevents
289
  // array type elements. This is good, since array type elements
290
  // cannot be supported properly in any case (no assignment,
291
  // copy works only if the tails are exactly the same type, ...)
292
293
  cons(typename access_traits<stored_head_type>::parameter_type h,
294
       const tail_type& t)
295
    : head (h), tail(t) {}
296
297
  template <class T1, class T2, class T3, class T4, class T5,
298
            class T6, class T7, class T8, class T9, class T10>
299
  cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
300
        T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
301
    : head (t1),
302
      tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
303
      {}
304
305
  template <class T2, class T3, class T4, class T5,
306
            class T6, class T7, class T8, class T9, class T10>
307
  cons( const null_type& /*t1*/, T2& t2, T3& t3, T4& t4, T5& t5,
308
        T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
309
    : head (),
310
      tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
311
      {}
312
313
  cons( const cons& u ) : head(u.head), tail(u.tail) {}
314
315
  template <class HT2, class TT2>
316
  cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}
317
318
  template <class HT2, class TT2>
319
  cons& operator=( const cons<HT2, TT2>& u ) {
320
    head=u.head; tail=u.tail; return *this;
321
  }
322
323
  // must define assignment operator explicitly, implicit version is
324
  // illformed if HT is a reference (12.8. (12))
325
  cons& operator=(const cons& u) {
326
    head = u.head; tail = u.tail;  return *this;
327
  }
328
329
  template <class T1, class T2>
330
  cons& operator=( const std::pair<T1, T2>& u ) {
331
    BOOST_STATIC_ASSERT(length<cons>::value == 2); // check length = 2
332
    head = u.first; tail.head = u.second; return *this;
333
  }
334
335
  // get member functions (non-const and const)
336
  template <int N>
337
  typename access_traits<
338
             typename element<N, cons<HT, TT> >::type
339
           >::non_const_type
340
  get() {
341
    return boost::tuples::get<N>(*this); // delegate to non-member get
342
  }
343
344
  template <int N>
345
  typename access_traits<
346
             typename element<N, cons<HT, TT> >::type
347
           >::const_type
348
  get() const {
349
    return boost::tuples::get<N>(*this); // delegate to non-member get
350
  }
351
};
352
353
template <class HT>
354
struct cons<HT, null_type> {
355
356
  typedef HT head_type;
357
  typedef null_type tail_type;
358
  typedef cons<HT, null_type> self_type;
359
360
  typedef typename
361
    detail::wrap_non_storeable_type<head_type>::type stored_head_type;
362
  stored_head_type head;
363
364
  typename access_traits<stored_head_type>::non_const_type
365
  get_head() { return head; }
366
367
  null_type get_tail() { return null_type(); }
368
369
  typename access_traits<stored_head_type>::const_type
370
  get_head() const { return head; }
371
372
  const null_type get_tail() const { return null_type(); }
373
374
  //  cons() : head(detail::default_arg<HT>::f()) {}
375
  cons() : head() {}
376
377
  cons(typename access_traits<stored_head_type>::parameter_type h,
378
       const null_type& = null_type())
379
    : head (h) {}
380
381
  template<class T1>
382
  cons(T1& t1, const null_type&, const null_type&, const null_type&,
383
       const null_type&, const null_type&, const null_type&,
384
       const null_type&, const null_type&, const null_type&)
385
  : head (t1) {}
386
387
  cons(const null_type&,
388
       const null_type&, const null_type&, const null_type&,
389
       const null_type&, const null_type&, const null_type&,
390
       const null_type&, const null_type&, const null_type&)
391
  : head () {}
392
393
  cons( const cons& u ) : head(u.head) {}
394
395
  template <class HT2>
396
  cons( const cons<HT2, null_type>& u ) : head(u.head) {}
397
398
  template <class HT2>
399
  cons& operator=(const cons<HT2, null_type>& u )
400
  { head = u.head; return *this; }
401
402
  // must define assignment operator explicitely, implicit version
403
  // is illformed if HT is a reference
404
  cons& operator=(const cons& u) { head = u.head; return *this; }
405
406
  template <int N>
407
  typename access_traits<
408
             typename element<N, self_type>::type
409
            >::non_const_type
410
  get() {
411
    return boost::tuples::get<N>(*this);
412
  }
413
414
  template <int N>
415
  typename access_traits<
416
             typename element<N, self_type>::type
417
           >::const_type
418
  get() const {
419
    return boost::tuples::get<N>(*this);
420
  }
421
422
};
423
424
// templates for finding out the length of the tuple -------------------
425
426
template<class T>
427
struct length: boost::integral_constant<int, 1 + length<typename T::tail_type>::value>
428
{
429
};
430
431
template<>
432
struct length<tuple<> >: boost::integral_constant<int, 0>
433
{
434
};
435
436
template<>
437
struct length<tuple<> const>: boost::integral_constant<int, 0>
438
{
439
};
440
441
template<>
442
struct length<null_type>: boost::integral_constant<int, 0>
443
{
444
};
445
446
template<>
447
struct length<null_type const>: boost::integral_constant<int, 0>
448
{
449
};
450
451
namespace detail {
452
453
// Tuple to cons mapper --------------------------------------------------
454
template <class T0, class T1, class T2, class T3, class T4,
455
          class T5, class T6, class T7, class T8, class T9>
456
struct map_tuple_to_cons
457
{
458
  typedef cons<T0,
459
               typename map_tuple_to_cons<T1, T2, T3, T4, T5,
460
                                          T6, T7, T8, T9, null_type>::type
461
              > type;
462
};
463
464
// The empty tuple is a null_type
465
template <>
466
struct map_tuple_to_cons<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>
467
{
468
  typedef null_type type;
469
};
470
471
} // end detail
472
473
// -------------------------------------------------------------------
474
// -- tuple ------------------------------------------------------
475
template <class T0, class T1, class T2, class T3, class T4,
476
          class T5, class T6, class T7, class T8, class T9>
477
478
class tuple :
479
  public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
480
{
481
public:
482
  typedef typename
483
    detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
484
  typedef typename inherited::head_type head_type;
485
  typedef typename inherited::tail_type tail_type;
486
487
488
// access_traits<T>::parameter_type takes non-reference types as const T&
489
  tuple() {}
490
491
  explicit tuple(typename access_traits<T0>::parameter_type t0)
492
    : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(),
493
                detail::cnull(), detail::cnull(), detail::cnull(),
494
                detail::cnull(), detail::cnull(), detail::cnull()) {}
495
496
  tuple(typename access_traits<T0>::parameter_type t0,
497
        typename access_traits<T1>::parameter_type t1)
498
    : inherited(t0, t1, detail::cnull(), detail::cnull(),
499
                detail::cnull(), detail::cnull(), detail::cnull(),
500
                detail::cnull(), detail::cnull(), detail::cnull()) {}
501
502
  tuple(typename access_traits<T0>::parameter_type t0,
503
        typename access_traits<T1>::parameter_type t1,
504
        typename access_traits<T2>::parameter_type t2)
505
    : inherited(t0, t1, t2, detail::cnull(), detail::cnull(),
506
                detail::cnull(), detail::cnull(), detail::cnull(),
507
                detail::cnull(), detail::cnull()) {}
508
509
  tuple(typename access_traits<T0>::parameter_type t0,
510
        typename access_traits<T1>::parameter_type t1,
511
        typename access_traits<T2>::parameter_type t2,
512
        typename access_traits<T3>::parameter_type t3)
513
    : inherited(t0, t1, t2, t3, detail::cnull(), detail::cnull(),
514
                detail::cnull(), detail::cnull(), detail::cnull(),
515
                detail::cnull()) {}
516
517
  tuple(typename access_traits<T0>::parameter_type t0,
518
        typename access_traits<T1>::parameter_type t1,
519
        typename access_traits<T2>::parameter_type t2,
520
        typename access_traits<T3>::parameter_type t3,
521
        typename access_traits<T4>::parameter_type t4)
522
    : inherited(t0, t1, t2, t3, t4, detail::cnull(), detail::cnull(),
523
                detail::cnull(), detail::cnull(), detail::cnull()) {}
524
525
  tuple(typename access_traits<T0>::parameter_type t0,
526
        typename access_traits<T1>::parameter_type t1,
527
        typename access_traits<T2>::parameter_type t2,
528
        typename access_traits<T3>::parameter_type t3,
529
        typename access_traits<T4>::parameter_type t4,
530
        typename access_traits<T5>::parameter_type t5)
531
    : inherited(t0, t1, t2, t3, t4, t5, detail::cnull(), detail::cnull(),
532
                detail::cnull(), detail::cnull()) {}
533
534
  tuple(typename access_traits<T0>::parameter_type t0,
535
        typename access_traits<T1>::parameter_type t1,
536
        typename access_traits<T2>::parameter_type t2,
537
        typename access_traits<T3>::parameter_type t3,
538
        typename access_traits<T4>::parameter_type t4,
539
        typename access_traits<T5>::parameter_type t5,
540
        typename access_traits<T6>::parameter_type t6)
541
    : inherited(t0, t1, t2, t3, t4, t5, t6, detail::cnull(),
542
                detail::cnull(), detail::cnull()) {}
543
544
  tuple(typename access_traits<T0>::parameter_type t0,
545
        typename access_traits<T1>::parameter_type t1,
546
        typename access_traits<T2>::parameter_type t2,
547
        typename access_traits<T3>::parameter_type t3,
548
        typename access_traits<T4>::parameter_type t4,
549
        typename access_traits<T5>::parameter_type t5,
550
        typename access_traits<T6>::parameter_type t6,
551
        typename access_traits<T7>::parameter_type t7)
552
    : inherited(t0, t1, t2, t3, t4, t5, t6, t7, detail::cnull(),
553
                detail::cnull()) {}
554
555
  tuple(typename access_traits<T0>::parameter_type t0,
556
        typename access_traits<T1>::parameter_type t1,
557
        typename access_traits<T2>::parameter_type t2,
558
        typename access_traits<T3>::parameter_type t3,
559
        typename access_traits<T4>::parameter_type t4,
560
        typename access_traits<T5>::parameter_type t5,
561
        typename access_traits<T6>::parameter_type t6,
562
        typename access_traits<T7>::parameter_type t7,
563
        typename access_traits<T8>::parameter_type t8)
564
    : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, detail::cnull()) {}
565
566
  tuple(typename access_traits<T0>::parameter_type t0,
567
        typename access_traits<T1>::parameter_type t1,
568
        typename access_traits<T2>::parameter_type t2,
569
        typename access_traits<T3>::parameter_type t3,
570
        typename access_traits<T4>::parameter_type t4,
571
        typename access_traits<T5>::parameter_type t5,
572
        typename access_traits<T6>::parameter_type t6,
573
        typename access_traits<T7>::parameter_type t7,
574
        typename access_traits<T8>::parameter_type t8,
575
        typename access_traits<T9>::parameter_type t9)
576
    : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {}
577
578
579
  template<class U1, class U2>
580
  tuple(const cons<U1, U2>& p) : inherited(p) {}
581
582
  template <class U1, class U2>
583
  tuple& operator=(const cons<U1, U2>& k) {
584
    inherited::operator=(k);
585
    return *this;
586
  }
587
588
  template <class U1, class U2>
589
  tuple& operator=(const std::pair<U1, U2>& k) {
590
    BOOST_STATIC_ASSERT(length<tuple>::value == 2);// check_length = 2
591
    this->head = k.first;
592
    this->tail.head = k.second;
593
    return *this;
594
  }
595
596
};
597
598
// The empty tuple
599
template <>
600
class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>  :
601
  public null_type
602
{
603
public:
604
  typedef null_type inherited;
605
};
606
607
608
// Swallows any assignment   (by Doug Gregor)
609
namespace detail {
610
611
struct swallow_assign;
612
typedef void (detail::swallow_assign::*ignore_t)();
613
struct swallow_assign {
614
0
  swallow_assign(ignore_t(*)(ignore_t)) {}
615
  template<typename T>
616
  swallow_assign const& operator=(const T&) const {
617
    return *this;
618
  }
619
};
620
621
622
} // namespace detail
623
624
// "ignore" allows tuple positions to be ignored when using "tie".
625
0
inline detail::ignore_t ignore(detail::ignore_t) { return 0; }
626
627
// ---------------------------------------------------------------------------
628
// The call_traits for make_tuple
629
// Honours the reference_wrapper class.
630
631
// Must be instantiated with plain or const plain types (not with references)
632
633
// from template<class T> foo(const T& t) : make_tuple_traits<const T>::type
634
// from template<class T> foo(T& t) : make_tuple_traits<T>::type
635
636
// Conversions:
637
// T -> T,
638
// references -> compile_time_error
639
// reference_wrapper<T> -> T&
640
// const reference_wrapper<T> -> T&
641
// array -> const ref array
642
643
644
template<class T>
645
struct make_tuple_traits {
646
  typedef T type;
647
648
  // commented away, see below  (JJ)
649
  //  typedef typename IF<
650
  //  boost::is_function<T>::value,
651
  //  T&,
652
  //  T>::RET type;
653
654
};
655
656
// The is_function test was there originally for plain function types,
657
// which can't be stored as such (we must either store them as references or
658
// pointers). Such a type could be formed if make_tuple was called with a
659
// reference to a function.
660
// But this would mean that a const qualified function type was formed in
661
// the make_tuple function and hence make_tuple can't take a function
662
// reference as a parameter, and thus T can't be a function type.
663
// So is_function test was removed.
664
// (14.8.3. says that type deduction fails if a cv-qualified function type
665
// is created. (It only applies for the case of explicitly specifying template
666
// args, though?)) (JJ)
667
668
template<class T>
669
struct make_tuple_traits<T&> {
670
  typedef typename
671
     detail::generate_error<T&>::
672
       do_not_use_with_reference_type error;
673
};
674
675
// Arrays can't be stored as plain types; convert them to references.
676
// All arrays are converted to const. This is because make_tuple takes its
677
// parameters as const T& and thus the knowledge of the potential
678
// non-constness of actual argument is lost.
679
template<class T, int n>  struct make_tuple_traits <T[n]> {
680
  typedef const T (&type)[n];
681
};
682
683
template<class T, int n>
684
struct make_tuple_traits<const T[n]> {
685
  typedef const T (&type)[n];
686
};
687
688
template<class T, int n>  struct make_tuple_traits<volatile T[n]> {
689
  typedef const volatile T (&type)[n];
690
};
691
692
template<class T, int n>
693
struct make_tuple_traits<const volatile T[n]> {
694
  typedef const volatile T (&type)[n];
695
};
696
697
template<class T>
698
struct make_tuple_traits<reference_wrapper<T> >{
699
  typedef T& type;
700
};
701
702
template<class T>
703
struct make_tuple_traits<const reference_wrapper<T> >{
704
  typedef T& type;
705
};
706
707
template<>
708
struct make_tuple_traits<detail::ignore_t(detail::ignore_t)> {
709
  typedef detail::swallow_assign type;
710
};
711
712
713
714
namespace detail {
715
716
// a helper traits to make the make_tuple functions shorter (Vesa Karvonen's
717
// suggestion)
718
template <
719
  class T0 = null_type, class T1 = null_type, class T2 = null_type,
720
  class T3 = null_type, class T4 = null_type, class T5 = null_type,
721
  class T6 = null_type, class T7 = null_type, class T8 = null_type,
722
  class T9 = null_type
723
>
724
struct make_tuple_mapper {
725
  typedef
726
    tuple<typename make_tuple_traits<T0>::type,
727
          typename make_tuple_traits<T1>::type,
728
          typename make_tuple_traits<T2>::type,
729
          typename make_tuple_traits<T3>::type,
730
          typename make_tuple_traits<T4>::type,
731
          typename make_tuple_traits<T5>::type,
732
          typename make_tuple_traits<T6>::type,
733
          typename make_tuple_traits<T7>::type,
734
          typename make_tuple_traits<T8>::type,
735
          typename make_tuple_traits<T9>::type> type;
736
};
737
738
} // end detail
739
740
// -make_tuple function templates -----------------------------------
741
0
inline tuple<> make_tuple() {
742
0
  return tuple<>();
743
0
}
744
745
template<class T0>
746
inline typename detail::make_tuple_mapper<T0>::type
747
make_tuple(const T0& t0) {
748
  typedef typename detail::make_tuple_mapper<T0>::type t;
749
  return t(t0);
750
}
751
752
template<class T0, class T1>
753
inline typename detail::make_tuple_mapper<T0, T1>::type
754
make_tuple(const T0& t0, const T1& t1) {
755
  typedef typename detail::make_tuple_mapper<T0, T1>::type t;
756
  return t(t0, t1);
757
}
758
759
template<class T0, class T1, class T2>
760
inline typename detail::make_tuple_mapper<T0, T1, T2>::type
761
make_tuple(const T0& t0, const T1& t1, const T2& t2) {
762
  typedef typename detail::make_tuple_mapper<T0, T1, T2>::type t;
763
  return t(t0, t1, t2);
764
}
765
766
template<class T0, class T1, class T2, class T3>
767
inline typename detail::make_tuple_mapper<T0, T1, T2, T3>::type
768
make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
769
  typedef typename detail::make_tuple_mapper<T0, T1, T2, T3>::type t;
770
  return t(t0, t1, t2, t3);
771
}
772
773
template<class T0, class T1, class T2, class T3, class T4>
774
inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type
775
make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
776
                  const T4& t4) {
777
  typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type t;
778
  return t(t0, t1, t2, t3, t4);
779
}
780
781
template<class T0, class T1, class T2, class T3, class T4, class T5>
782
inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type
783
make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
784
                  const T4& t4, const T5& t5) {
785
  typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type t;
786
  return t(t0, t1, t2, t3, t4, t5);
787
}
788
789
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
790
inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6>::type
791
make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
792
                  const T4& t4, const T5& t5, const T6& t6) {
793
  typedef typename detail::make_tuple_mapper
794
           <T0, T1, T2, T3, T4, T5, T6>::type t;
795
  return t(t0, t1, t2, t3, t4, t5, t6);
796
}
797
798
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
799
         class T7>
800
inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
801
make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
802
                  const T4& t4, const T5& t5, const T6& t6, const T7& t7) {
803
  typedef typename detail::make_tuple_mapper
804
           <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
805
  return t(t0, t1, t2, t3, t4, t5, t6, t7);
806
}
807
808
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
809
         class T7, class T8>
810
inline typename detail::make_tuple_mapper
811
  <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
812
make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
813
                  const T4& t4, const T5& t5, const T6& t6, const T7& t7,
814
                  const T8& t8) {
815
  typedef typename detail::make_tuple_mapper
816
           <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
817
  return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
818
}
819
820
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
821
         class T7, class T8, class T9>
822
inline typename detail::make_tuple_mapper
823
  <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
824
make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
825
                  const T4& t4, const T5& t5, const T6& t6, const T7& t7,
826
                  const T8& t8, const T9& t9) {
827
  typedef typename detail::make_tuple_mapper
828
           <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
829
  return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
830
}
831
832
namespace detail {
833
834
template<class T>
835
struct tie_traits {
836
  typedef T& type;
837
};
838
839
template<>
840
struct tie_traits<ignore_t(ignore_t)> {
841
  typedef swallow_assign type;
842
};
843
844
template<>
845
struct tie_traits<void> {
846
  typedef null_type type;
847
};
848
849
template <
850
  class T0 = void, class T1 = void, class T2 = void,
851
  class T3 = void, class T4 = void, class T5 = void,
852
  class T6 = void, class T7 = void, class T8 = void,
853
  class T9 = void
854
>
855
struct tie_mapper {
856
  typedef
857
    tuple<typename tie_traits<T0>::type,
858
          typename tie_traits<T1>::type,
859
          typename tie_traits<T2>::type,
860
          typename tie_traits<T3>::type,
861
          typename tie_traits<T4>::type,
862
          typename tie_traits<T5>::type,
863
          typename tie_traits<T6>::type,
864
          typename tie_traits<T7>::type,
865
          typename tie_traits<T8>::type,
866
          typename tie_traits<T9>::type> type;
867
};
868
869
}
870
871
// Tie function templates -------------------------------------------------
872
template<class T0>
873
inline typename detail::tie_mapper<T0>::type
874
tie(T0& t0) {
875
  typedef typename detail::tie_mapper<T0>::type t;
876
  return t(t0);
877
}
878
879
template<class T0, class T1>
880
inline typename detail::tie_mapper<T0, T1>::type
881
tie(T0& t0, T1& t1) {
882
  typedef typename detail::tie_mapper<T0, T1>::type t;
883
  return t(t0, t1);
884
}
885
886
template<class T0, class T1, class T2>
887
inline typename detail::tie_mapper<T0, T1, T2>::type
888
tie(T0& t0, T1& t1, T2& t2) {
889
  typedef typename detail::tie_mapper<T0, T1, T2>::type t;
890
  return t(t0, t1, t2);
891
}
892
893
template<class T0, class T1, class T2, class T3>
894
inline typename detail::tie_mapper<T0, T1, T2, T3>::type
895
tie(T0& t0, T1& t1, T2& t2, T3& t3) {
896
  typedef typename detail::tie_mapper<T0, T1, T2, T3>::type t;
897
  return t(t0, t1, t2, t3);
898
}
899
900
template<class T0, class T1, class T2, class T3, class T4>
901
inline typename detail::tie_mapper<T0, T1, T2, T3, T4>::type
902
tie(T0& t0, T1& t1, T2& t2, T3& t3,
903
                  T4& t4) {
904
  typedef typename detail::tie_mapper<T0, T1, T2, T3, T4>::type t;
905
  return t(t0, t1, t2, t3, t4);
906
}
907
908
template<class T0, class T1, class T2, class T3, class T4, class T5>
909
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type
910
tie(T0& t0, T1& t1, T2& t2, T3& t3,
911
                  T4& t4, T5& t5) {
912
  typedef typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type t;
913
  return t(t0, t1, t2, t3, t4, t5);
914
}
915
916
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
917
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6>::type
918
tie(T0& t0, T1& t1, T2& t2, T3& t3,
919
                  T4& t4, T5& t5, T6& t6) {
920
  typedef typename detail::tie_mapper
921
           <T0, T1, T2, T3, T4, T5, T6>::type t;
922
  return t(t0, t1, t2, t3, t4, t5, t6);
923
}
924
925
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
926
         class T7>
927
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
928
tie(T0& t0, T1& t1, T2& t2, T3& t3,
929
                  T4& t4, T5& t5, T6& t6, T7& t7) {
930
  typedef typename detail::tie_mapper
931
           <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
932
  return t(t0, t1, t2, t3, t4, t5, t6, t7);
933
}
934
935
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
936
         class T7, class T8>
937
inline typename detail::tie_mapper
938
  <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
939
tie(T0& t0, T1& t1, T2& t2, T3& t3,
940
                  T4& t4, T5& t5, T6& t6, T7& t7,
941
                  T8& t8) {
942
  typedef typename detail::tie_mapper
943
           <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
944
  return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
945
}
946
947
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
948
         class T7, class T8, class T9>
949
inline typename detail::tie_mapper
950
  <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
951
tie(T0& t0, T1& t1, T2& t2, T3& t3,
952
                  T4& t4, T5& t5, T6& t6, T7& t7,
953
                  T8& t8, T9& t9) {
954
  typedef typename detail::tie_mapper
955
           <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
956
  return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
957
}
958
959
template <class T0, class T1, class T2, class T3, class T4,
960
          class T5, class T6, class T7, class T8, class T9>
961
void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
962
          tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
963
0
inline void swap(null_type&, null_type&) {}
964
template<class HH>
965
inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
966
  ::boost::swap(lhs.head, rhs.head);
967
}
968
template<class HH, class TT>
969
inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
970
  ::boost::swap(lhs.head, rhs.head);
971
  ::boost::tuples::swap(lhs.tail, rhs.tail);
972
}
973
template <class T0, class T1, class T2, class T3, class T4,
974
          class T5, class T6, class T7, class T8, class T9>
975
inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
976
          tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
977
  typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
978
  typedef typename tuple_type::inherited base;
979
  ::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
980
}
981
982
} // end of namespace tuples
983
} // end of namespace boost
984
985
986
#if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
987
#pragma GCC diagnostic pop
988
#endif
989
990
991
#endif // BOOST_TUPLE_BASIC_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/type_index.hpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Copyright 2012-2021 Antony Polukhin.
3
//
4
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
//
7
8
#ifndef BOOST_TYPE_INDEX_HPP
9
#define BOOST_TYPE_INDEX_HPP
10
11
/// \file boost/type_index.hpp
12
/// \brief Includes minimal set of headers required to use the Boost.TypeIndex library.
13
///
14
/// By inclusion of this file most optimal type index classes will be included and used 
15
/// as a boost::typeindex::type_index and boost::typeindex::type_info.
16
17
#include <boost/config.hpp>
18
19
#ifdef BOOST_HAS_PRAGMA_ONCE
20
# pragma once
21
#endif
22
23
#if defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
24
#   include BOOST_TYPE_INDEX_USER_TYPEINDEX
25
#   ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
26
#       pragma detect_mismatch( "boost__type_index__abi", "user defined type_index class is used: " BOOST_STRINGIZE(BOOST_TYPE_INDEX_USER_TYPEINDEX))
27
#   endif
28
#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
29
#   include <boost/type_index/stl_type_index.hpp>
30
#   if defined(BOOST_NO_RTTI) || defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)
31
#       include <boost/type_index/detail/stl_register_class.hpp>
32
#       ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
33
#           pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - typeid() is used only for templates")
34
#       endif
35
#   else
36
#       ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
37
#           pragma detect_mismatch( "boost__type_index__abi", "RTTI is used")
38
#       endif
39
#   endif
40
#else
41
#   include <boost/type_index/ctti_type_index.hpp>
42
#   include <boost/type_index/detail/ctti_register_class.hpp>
43
#   ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
44
#       pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - using CTTI")
45
#   endif
46
#endif
47
48
#ifndef BOOST_TYPE_INDEX_REGISTER_CLASS
49
#define BOOST_TYPE_INDEX_REGISTER_CLASS
50
#endif
51
52
namespace boost { namespace typeindex {
53
54
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
55
56
/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE
57
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::typeindex::ctti_type_index class to
58
/// deduce the name of a type. If your compiler is not recognized
59
/// by the TypeIndex library and you wish to work with boost::typeindex::ctti_type_index, you may
60
/// define this macro by yourself.
61
///
62
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro
63
/// that outputs the \b whole function signature \b including \b template \b parameters.
64
///
65
/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined,
66
/// then a compile-time error will arise at any attempt to use boost::typeindex::ctti_type_index classes.
67
///
68
/// See BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS and BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
69
/// for an information of how to tune the implementation to make a nice pretty_name() output.
70
#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION
71
72
/// \def BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
73
/// This is a helper macro for making correct pretty_names() with RTTI off.
74
///
75
/// BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING macro may be defined to
76
/// '(begin_skip, end_skip, runtime_skip, runtime_skip_until)' with parameters for adding a
77
/// support for compilers, that by default are not recognized by TypeIndex library.
78
///
79
/// \b Example:
80
///
81
/// Imagine the situation when
82
/// \code boost::typeindex::ctti_type_index::type_id<int>().pretty_name() \endcode
83
/// returns the following string:
84
/// \code "static const char *boost::detail::ctti<int>::n() [T = int]" \endcode
85
/// and \code boost::typeindex::ctti_type_index::type_id<short>().pretty_name() \endcode returns the following:
86
/// \code "static const char *boost::detail::ctti<short>::n() [T = short]" \endcode
87
///
88
/// As we may see first 39 characters are "static const char *boost::detail::ctti<" and they do not depend on
89
/// the type T. After first 39 characters we have a human readable type name which is duplicated at the end
90
/// of a string. String always ends on ']', which consumes 1 character.
91
///
92
/// Now if we define `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` to
93
/// `(39, 1, false, "")` we'll be getting \code "int>::n() [T = int" \endcode
94
/// for `boost::typeindex::ctti_type_index::type_id<int>().pretty_name()` and \code "short>::n() [T = short" \endcode
95
/// for `boost::typeindex::ctti_type_index::type_id<short>().pretty_name()`.
96
///
97
/// Now we need to take additional care of the characters that go before the last mention of our type. We'll
98
/// do that by telling the macro that we need to cut off everything that goes before the "T = " including the "T = "
99
/// itself:
100
///
101
/// \code (39, 1, true, "T = ") \endcode
102
///
103
/// In case of GCC or Clang command line we need to add the following line while compiling all the sources:
104
///
105
/// \code
106
/// -DBOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='(39, 1, true, "T = ")'
107
/// \endcode
108
/// \param begin_skip How many characters must be skipped at the beginning of the type holding string.
109
/// Must be a compile time constant.
110
/// \param end_skip How many characters must be skipped at the end of the type holding string.
111
/// Must be a compile time constant.
112
/// \param runtime_skip Do we need additional checks at runtime to cut off the more characters.
113
/// Must be `true` or `false`.
114
/// \param runtime_skip_until Skip all the characters before the following string (including the string itself).
115
/// Must be a compile time array of characters.
116
///
117
/// See [RTTI emulation limitations](boost_typeindex/rtti_emulation_limitations.html) for more info.
118
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (0, 0, false, "")
119
120
121
    /// Depending on a compiler flags, optimal implementation of type_index will be used 
122
    /// as a default boost::typeindex::type_index.
123
    ///
124
    /// Could be a boost::typeindex::stl_type_index, boost::typeindex::ctti_type_index or 
125
    /// user defined type_index class.
126
    ///
127
    /// \b See boost::typeindex::type_index_facade for a full description of type_index functions.
128
    typedef platform_specific type_index;
129
#elif defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
130
    // Nothing to do
131
#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
132
    typedef boost::typeindex::stl_type_index type_index;
133
#else 
134
    typedef boost::typeindex::ctti_type_index type_index;
135
#endif
136
137
/// Depending on a compiler flags, optimal implementation of type_info will be used 
138
/// as a default boost::typeindex::type_info.
139
///
140
/// Could be a std::type_info, boost::typeindex::detail::ctti_data or 
141
/// some user defined class.
142
///
143
/// type_info \b is \b not copyable or default constructible. It is \b not assignable too!
144
typedef type_index::type_info_t type_info;
145
146
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
147
148
/// \def BOOST_TYPE_INDEX_USER_TYPEINDEX
149
/// BOOST_TYPE_INDEX_USER_TYPEINDEX can be defined to the path to header file
150
/// with user provided implementation of type_index.
151
///
152
/// See [Making a custom type_index](boost_typeindex/making_a_custom_type_index.html) section
153
/// of documentation for usage example.
154
#define BOOST_TYPE_INDEX_USER_TYPEINDEX <full/absolute/path/to/header/with/type_index.hpp>
155
156
157
/// \def BOOST_TYPE_INDEX_REGISTER_CLASS
158
/// BOOST_TYPE_INDEX_REGISTER_CLASS is used to help to emulate RTTI.
159
/// Put this macro into the public section of polymorphic class to allow runtime type detection.
160
///
161
/// Depending on the typeid() availability this macro will expand to nothing or to virtual helper function
162
/// `virtual const type_info& boost_type_info_type_id_runtime_() const noexcept`.
163
///
164
/// \b Example:
165
/// \code
166
/// class A {
167
/// public:
168
///     BOOST_TYPE_INDEX_REGISTER_CLASS
169
///     virtual ~A(){}
170
/// };
171
///
172
/// struct B: public A {
173
///     BOOST_TYPE_INDEX_REGISTER_CLASS
174
/// };
175
///
176
/// struct C: public B {
177
///     BOOST_TYPE_INDEX_REGISTER_CLASS
178
/// };
179
///
180
/// ...
181
///
182
/// C c1;
183
/// A* pc1 = &c1;
184
/// assert(boost::typeindex::type_id<C>() == boost::typeindex::type_id_runtime(*pc1));
185
/// \endcode
186
#define BOOST_TYPE_INDEX_REGISTER_CLASS nothing-or-some-virtual-functions
187
188
/// \def BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
189
/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY is a helper macro that must be defined if mixing
190
/// RTTI on/off modules. See
191
/// [Mixing sources with RTTI on and RTTI off](boost_typeindex/mixing_sources_with_rtti_on_and_.html)
192
/// section of documentation for more info.
193
#define BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
194
195
#endif // defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
196
197
198
/// Function to get boost::typeindex::type_index for a type T.
199
/// Removes const, volatile && and & modifiers from T.
200
///
201
/// \b Example:
202
/// \code
203
/// type_index ti = type_id<int&>();
204
/// std::cout << ti.pretty_name();  // Outputs 'int'
205
/// \endcode
206
///
207
/// \tparam T Type for which type_index must be created.
208
/// \throw Nothing.
209
/// \return boost::typeindex::type_index with information about the specified type T.
210
template <class T>
211
0
inline type_index type_id() BOOST_NOEXCEPT {
212
0
    return type_index::type_id<T>();
213
0
}
Unexecuted instantiation: _ZN5boost9typeindex7type_idINS_9algorithm6detail13token_finderFINS3_10is_any_ofFIcEEEEEENS0_14stl_type_indexEv
Unexecuted instantiation: _ZN5boost9typeindex7type_idIvEENS0_14stl_type_indexEv
214
215
/// Function for constructing boost::typeindex::type_index instance for type T. 
216
/// Does not remove const, volatile, & and && modifiers from T.
217
///
218
/// If T has no const, volatile, & and && modifiers, then returns exactly 
219
/// the same result as in case of calling `type_id<T>()`.
220
///
221
/// \b Example:
222
/// \code
223
/// type_index ti = type_id_with_cvr<int&>();
224
/// std::cout << ti.pretty_name();  // Outputs 'int&'
225
/// \endcode
226
///
227
/// \tparam T Type for which type_index must be created.
228
/// \throw Nothing.
229
/// \return boost::typeindex::type_index with information about the specified type T.
230
template <class T>
231
inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
232
    return type_index::type_id_with_cvr<T>();
233
}
234
235
/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index.
236
///
237
/// Returns runtime information about specified type.
238
///
239
/// \b Requirements: RTTI available or Base and Derived classes must be marked with BOOST_TYPE_INDEX_REGISTER_CLASS.
240
///
241
/// \b Example:
242
/// \code
243
/// struct Base { virtual ~Base(){} };
244
/// struct Derived: public Base  {};
245
/// ...
246
/// Derived d;
247
/// Base& b = d;
248
/// type_index ti = type_id_runtime(b);
249
/// std::cout << ti.pretty_name();  // Outputs 'Derived'
250
/// \endcode
251
///
252
/// \param runtime_val Variable which runtime type must be returned.
253
/// \throw Nothing.
254
/// \return boost::typeindex::type_index with information about the specified variable.
255
template <class T>
256
inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT {
257
    return type_index::type_id_runtime(runtime_val);
258
}
259
260
}} // namespace boost::typeindex
261
262
263
264
#endif // BOOST_TYPE_INDEX_HPP
265
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/type_index/stl_type_index.hpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Copyright 2013-2021 Antony Polukhin.
3
//
4
//
5
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
//
8
9
#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
10
#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
11
12
/// \file stl_type_index.hpp
13
/// \brief Contains boost::typeindex::stl_type_index class.
14
///
15
/// boost::typeindex::stl_type_index class can be used as a drop-in replacement 
16
/// for std::type_index.
17
///
18
/// It is used in situations when RTTI is enabled or typeid() method is available.
19
/// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro
20
/// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index.
21
22
#include <boost/type_index/type_index_facade.hpp>
23
24
// MSVC is capable of calling typeid(T) even when RTTI is off
25
#if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC)
26
#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available."
27
#endif
28
29
#include <typeinfo>
30
#include <cstring>                                  // std::strcmp, std::strlen, std::strstr
31
#include <stdexcept>
32
#include <boost/static_assert.hpp>
33
#include <boost/throw_exception.hpp>
34
#include <boost/core/demangle.hpp>
35
#include <boost/type_traits/conditional.hpp>
36
#include <boost/type_traits/is_const.hpp>
37
#include <boost/type_traits/is_reference.hpp>
38
#include <boost/type_traits/is_volatile.hpp>
39
#include <boost/type_traits/remove_cv.hpp>
40
#include <boost/type_traits/remove_reference.hpp>
41
42
#if (defined(_MSC_VER) && _MSC_VER > 1600) \
43
    || (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) \
44
    || (defined(__GNUC__) && __GNUC__ > 4 && __cplusplus >= 201103)
45
#   define BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
46
#else
47
#   include <boost/container_hash/hash.hpp>
48
#endif
49
50
#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
51
        || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
52
#   include <boost/type_traits/is_signed.hpp>
53
#   include <boost/type_traits/make_signed.hpp>
54
#   include <boost/type_traits/type_identity.hpp>
55
#endif
56
57
#ifdef BOOST_HAS_PRAGMA_ONCE
58
# pragma once
59
#endif
60
61
namespace boost { namespace typeindex {
62
63
/// \class stl_type_index
64
/// This class is a wrapper around std::type_info, that workarounds issues and provides
65
/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
66
///
67
/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index.
68
class stl_type_index
69
    : public type_index_facade<
70
        stl_type_index, 
71
        #ifdef BOOST_NO_STD_TYPEINFO
72
            type_info
73
        #else
74
            std::type_info
75
        #endif
76
    > 
77
{
78
public:
79
#ifdef BOOST_NO_STD_TYPEINFO
80
    typedef type_info type_info_t;
81
#else
82
    typedef std::type_info type_info_t;
83
#endif
84
85
private:
86
    const type_info_t* data_;
87
88
public:
89
    inline stl_type_index() BOOST_NOEXCEPT
90
        : data_(&typeid(void))
91
0
    {}
92
93
    inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT
94
        : data_(&data)
95
0
    {}
96
97
    inline const type_info_t&  type_info() const BOOST_NOEXCEPT;
98
99
    inline const char*  raw_name() const BOOST_NOEXCEPT;
100
    inline const char*  name() const BOOST_NOEXCEPT;
101
    inline std::string  pretty_name() const;
102
103
    inline std::size_t  hash_code() const BOOST_NOEXCEPT;
104
    inline bool         equal(const stl_type_index& rhs) const BOOST_NOEXCEPT;
105
    inline bool         before(const stl_type_index& rhs) const BOOST_NOEXCEPT;
106
107
    template <class T>
108
    inline static stl_type_index type_id() BOOST_NOEXCEPT;
109
110
    template <class T>
111
    inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT;
112
113
    template <class T>
114
    inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT;
115
};
116
117
0
inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT {
118
0
    return *data_;
119
0
}
120
121
122
0
inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT {
123
#ifdef _MSC_VER
124
    return data_->raw_name();
125
#else
126
0
    return data_->name();
127
0
#endif
128
0
}
129
130
0
inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
131
0
    return data_->name();
132
0
}
133
134
0
inline std::string stl_type_index::pretty_name() const {
135
0
    static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
136
0
    static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;
137
0
138
0
    // In case of MSVC demangle() is a no-op, and name() already returns demangled name.
139
0
    // In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it.
140
0
    const boost::core::scoped_demangled_name demangled_name(data_->name());
141
0
142
0
    const char* begin = demangled_name.get();
143
0
    if (!begin) {
144
0
        boost::throw_exception(std::runtime_error("Type name demangling failed"));
145
0
    }
146
0
147
0
    const std::string::size_type len = std::strlen(begin);
148
0
    const char* end = begin + len;
149
0
150
0
    if (len > cvr_saver_name_len) {
151
0
        const char* b = std::strstr(begin, cvr_saver_name);
152
0
        if (b) {
153
0
            b += cvr_saver_name_len;
154
0
155
0
            // Trim leading spaces
156
0
            while (*b == ' ') {         // the string is zero terminated, we won't exceed the buffer size
157
0
                ++ b;
158
0
            }
159
0
160
0
            // Skip the closing angle bracket
161
0
            const char* e = end - 1;
162
0
            while (e > b && *e != '>') {
163
0
                -- e;
164
0
            }
165
0
166
0
            // Trim trailing spaces
167
0
            while (e > b && *(e - 1) == ' ') {
168
0
                -- e;
169
0
            }
170
0
171
0
            if (b < e) {
172
0
                // Parsing seems to have succeeded, the type name is not empty
173
0
                begin = b;
174
0
                end = e;
175
0
            }
176
0
        }
177
0
    }
178
0
179
0
    return std::string(begin, end);
180
0
}
181
182
183
0
inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
184
0
#ifdef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
185
0
    return data_->hash_code();
186
0
#else
187
0
    return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
188
0
#endif
189
0
}
190
191
192
/// @cond
193
194
// for this compiler at least, cross-shared-library type_info
195
// comparisons don't work, so we are using typeid(x).name() instead.
196
# if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))) \
197
    || defined(_AIX) \
198
    || (defined(__sgi) && defined(__host_mips)) \
199
    || (defined(__hpux) && defined(__HP_aCC)) \
200
    || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
201
#  define BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
202
# endif
203
204
/// @endcond
205
206
0
inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT {
207
0
#ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
208
0
    return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
209
#else
210
    return !!(*data_ == *rhs.data_);
211
#endif
212
0
}
213
214
0
inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT {
215
0
#ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
216
0
    return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
217
0
#else
218
0
    return !!data_->before(*rhs.data_);
219
0
#endif
220
0
}
221
222
#undef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
223
224
225
template <class T>
226
0
inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT {
227
0
    typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
228
0
    typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_prefinal_t;
229
230
    #  if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
231
        || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
232
233
        // Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
234
        // in typeid() expressions. Full template specialization for 'integral' fixes that issue:
235
        typedef BOOST_DEDUCED_TYPENAME boost::conditional<
236
            boost::is_signed<no_cvr_prefinal_t>::value,
237
            boost::make_signed<no_cvr_prefinal_t>,
238
            boost::type_identity<no_cvr_prefinal_t>
239
        >::type no_cvr_prefinal_lazy_t;
240
241
        typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t;
242
    #else
243
0
        typedef no_cvr_prefinal_t no_cvr_t;
244
0
    #endif
245
246
0
    return typeid(no_cvr_t);
247
0
}
Unexecuted instantiation: _ZN5boost9typeindex14stl_type_index7type_idINS_9algorithm6detail13token_finderFINS4_10is_any_ofFIcEEEEEES1_v
Unexecuted instantiation: _ZN5boost9typeindex14stl_type_index7type_idIvEES1_v
248
249
namespace detail {
250
    template <class T> class cvr_saver{};
251
}
252
253
template <class T>
254
inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
255
    typedef BOOST_DEDUCED_TYPENAME boost::conditional<
256
        boost::is_reference<T>::value ||  boost::is_const<T>::value || boost::is_volatile<T>::value,
257
        detail::cvr_saver<T>,
258
        T
259
    >::type type;
260
261
    return typeid(type);
262
}
263
264
265
template <class T>
266
inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT {
267
#ifdef BOOST_NO_RTTI
268
    return value.boost_type_index_type_id_runtime_();
269
#else
270
    return typeid(value);
271
#endif
272
}
273
274
}} // namespace boost::typeindex
275
276
#undef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
277
278
#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/type_index/type_index_facade.hpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Copyright 2013-2021 Antony Polukhin.
3
//
4
//
5
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
//
8
9
#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
10
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
11
12
#include <boost/config.hpp>
13
#include <boost/container_hash/hash_fwd.hpp>
14
#include <string>
15
#include <cstring>
16
17
#if !defined(BOOST_NO_IOSTREAM)
18
#if !defined(BOOST_NO_IOSFWD)
19
#include <iosfwd>               // for std::basic_ostream
20
#else
21
#include <ostream>
22
#endif
23
#endif
24
25
#ifdef BOOST_HAS_PRAGMA_ONCE
26
# pragma once
27
#endif
28
29
namespace boost { namespace typeindex {
30
31
/// \class type_index_facade
32
///
33
/// This class takes care about the comparison operators, hash functions and 
34
/// ostream operators. Use this class as a public base class for defining new
35
/// type_info-conforming classes.
36
///
37
/// \b Example:
38
/// \code
39
/// class stl_type_index: public type_index_facade<stl_type_index, std::type_info> 
40
/// {
41
/// public:
42
///     typedef std::type_info type_info_t;
43
/// private:
44
///     const type_info_t* data_;
45
///
46
/// public:
47
///     stl_type_index(const type_info_t& data) noexcept
48
///         : data_(&data)
49
///     {}
50
/// // ...
51
/// };
52
/// \endcode
53
///
54
/// \tparam Derived Class derived from type_index_facade.
55
/// \tparam TypeInfo Class that will be used as a base type_info class.
56
/// \note Take a look at the protected methods. They are \b not \b defined in type_index_facade. 
57
/// Protected member functions raw_name() \b must be defined in Derived class. All the other 
58
/// methods are mandatory.
59
/// \see 'Making a custom type_index' section for more information about 
60
/// creating your own type_index using type_index_facade.
61
template <class Derived, class TypeInfo>
62
class type_index_facade {
63
private:
64
    /// @cond
65
    BOOST_CXX14_CONSTEXPR const Derived & derived() const BOOST_NOEXCEPT {
66
      return *static_cast<Derived const*>(this);
67
    }
68
    /// @endcond
69
public:
70
    typedef TypeInfo                                type_info_t;
71
72
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
73
    /// \return Name of a type. By default returns Derived::raw_name().
74
    inline const char* name() const BOOST_NOEXCEPT {
75
        return derived().raw_name();
76
    }
77
78
    /// \b Override: This function \b may be redefined in Derived class. Overrides may throw.
79
    /// \return Human readable type name. By default returns Derived::name().
80
    inline std::string pretty_name() const {
81
        return derived().name();
82
    }
83
84
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
85
    /// \return True if two types are equal. By default compares types by raw_name().
86
    inline bool equal(const Derived& rhs) const BOOST_NOEXCEPT {
87
        const char* const left = derived().raw_name();
88
        const char* const right = rhs.raw_name();
89
        return left == right || !std::strcmp(left, right);
90
    }
91
92
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
93
    /// \return True if rhs is greater than this. By default compares types by raw_name().
94
    inline bool before(const Derived& rhs) const BOOST_NOEXCEPT {
95
        const char* const left = derived().raw_name();
96
        const char* const right = rhs.raw_name();
97
        return left != right && std::strcmp(left, right) < 0;
98
    }
99
100
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
101
    /// \return Hash code of a type. By default hashes types by raw_name().
102
    /// \note Derived class header \b must include <boost/container_hash/hash.hpp>, \b unless this function is redefined in
103
    /// Derived class to not use boost::hash_range().
104
    inline std::size_t hash_code() const BOOST_NOEXCEPT {
105
        const char* const name_raw = derived().raw_name();
106
        return boost::hash_range(name_raw, name_raw + std::strlen(name_raw));
107
    }
108
109
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
110
protected:
111
    /// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
112
    /// \return Pointer to unredable/raw type name.
113
    inline const char* raw_name() const BOOST_NOEXCEPT;
114
115
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
116
    /// \return Const reference to underlying low level type_info_t.
117
    inline const type_info_t& type_info() const BOOST_NOEXCEPT;
118
119
    /// This is a factory method that is used to create instances of Derived classes.
120
    /// boost::typeindex::type_id() will call this method, if Derived has same type as boost::typeindex::type_index.
121
    ///
122
    /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw. 
123
    /// Overrides \b must remove const, volatile && and & modifiers from T.
124
    /// \tparam T Type for which type_index must be created.
125
    /// \return type_index for type T.
126
    template <class T>
127
    static Derived type_id() BOOST_NOEXCEPT;
128
129
    /// This is a factory method that is used to create instances of Derived classes.
130
    /// boost::typeindex::type_id_with_cvr() will call this method, if Derived has same type as boost::typeindex::type_index.
131
    ///
132
    /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw. 
133
    /// Overrides \b must \b not remove const, volatile && and & modifiers from T.
134
    /// \tparam T Type for which type_index must be created.
135
    /// \return type_index for type T.
136
    template <class T>
137
    static Derived type_id_with_cvr() BOOST_NOEXCEPT;
138
139
    /// This is a factory method that is used to create instances of Derived classes.
140
    /// boost::typeindex::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeindex::type_index.
141
    ///
142
    /// \b Override: This function \b may be redefined and made public in Derived class.
143
    /// \param variable Variable which runtime type will be stored in type_index.
144
    /// \return type_index with runtime type of variable.
145
    template <class T>
146
    static Derived type_id_runtime(const T& variable) BOOST_NOEXCEPT;
147
148
#endif
149
150
};
151
152
/// @cond
153
template <class Derived, class TypeInfo>
154
0
BOOST_CXX14_CONSTEXPR inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
155
0
    return static_cast<Derived const&>(lhs).equal(static_cast<Derived const&>(rhs));
156
0
}
157
158
template <class Derived, class TypeInfo>
159
BOOST_CXX14_CONSTEXPR inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
160
    return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));
161
}
162
163
164
165
template <class Derived, class TypeInfo>
166
BOOST_CXX14_CONSTEXPR inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
167
    return rhs < lhs;
168
}
169
170
template <class Derived, class TypeInfo>
171
BOOST_CXX14_CONSTEXPR inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
172
    return !(lhs > rhs);
173
}
174
175
template <class Derived, class TypeInfo>
176
BOOST_CXX14_CONSTEXPR inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
177
    return !(lhs < rhs);
178
}
179
180
template <class Derived, class TypeInfo>
181
BOOST_CXX14_CONSTEXPR inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
182
    return !(lhs == rhs);
183
}
184
185
// ######################### COMPARISONS with Derived ############################ //
186
template <class Derived, class TypeInfo>
187
0
inline bool operator == (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
188
0
    return Derived(lhs) == rhs;
189
0
}
190
191
template <class Derived, class TypeInfo>
192
inline bool operator < (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
193
    return Derived(lhs) < rhs;
194
}
195
196
template <class Derived, class TypeInfo>
197
inline bool operator > (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
198
    return rhs < Derived(lhs);
199
}
200
201
template <class Derived, class TypeInfo>
202
inline bool operator <= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
203
    return !(Derived(lhs) > rhs);
204
}
205
206
template <class Derived, class TypeInfo>
207
inline bool operator >= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
208
    return !(Derived(lhs) < rhs);
209
}
210
211
template <class Derived, class TypeInfo>
212
inline bool operator != (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
213
    return !(Derived(lhs) == rhs);
214
}
215
216
217
template <class Derived, class TypeInfo>
218
inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
219
    return lhs == Derived(rhs);
220
}
221
222
template <class Derived, class TypeInfo>
223
inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
224
    return lhs < Derived(rhs);
225
}
226
227
template <class Derived, class TypeInfo>
228
inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
229
    return Derived(rhs) < lhs;
230
}
231
232
template <class Derived, class TypeInfo>
233
inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
234
    return !(lhs > Derived(rhs));
235
}
236
237
template <class Derived, class TypeInfo>
238
inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
239
    return !(lhs < Derived(rhs));
240
}
241
242
template <class Derived, class TypeInfo>
243
inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
244
    return !(lhs == Derived(rhs));
245
}
246
247
// ######################### COMPARISONS with Derived END ############################ //
248
249
/// @endcond
250
251
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
252
253
/// noexcept comparison operators for type_index_facade classes.
254
bool operator ==, !=, <, ... (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;
255
256
/// noexcept comparison operators for type_index_facade and it's TypeInfo classes.
257
bool operator ==, !=, <, ... (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;
258
259
/// noexcept comparison operators for type_index_facade's TypeInfo and type_index_facade classes.
260
bool operator ==, !=, <, ... (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
261
262
#endif
263
264
#ifndef BOOST_NO_IOSTREAM
265
#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
266
/// @cond
267
/// Ostream operator that will output demangled name
268
template <class Derived, class TypeInfo>
269
inline std::ostream& operator<<(std::ostream& ostr, const type_index_facade<Derived, TypeInfo>& ind) {
270
    ostr << static_cast<Derived const&>(ind).pretty_name();
271
    return ostr;
272
}
273
/// @endcond
274
#else
275
/// Ostream operator that will output demangled name.
276
template <class CharT, class TriatT, class Derived, class TypeInfo>
277
inline std::basic_ostream<CharT, TriatT>& operator<<(
278
    std::basic_ostream<CharT, TriatT>& ostr, 
279
    const type_index_facade<Derived, TypeInfo>& ind) 
280
{
281
    ostr << static_cast<Derived const&>(ind).pretty_name();
282
    return ostr;
283
}
284
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
285
#endif // BOOST_NO_IOSTREAM
286
287
/// This free function is used by Boost's unordered containers.
288
/// \note <boost/container_hash/hash.hpp> has to be included if this function is used.
289
template <class Derived, class TypeInfo>
290
inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) BOOST_NOEXCEPT {
291
    return static_cast<Derived const&>(lhs).hash_code();
292
}
293
294
}} // namespace boost::typeindex
295
296
#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
297
/opt/homebrew/Cellar/boost@1.76/1.76.0_4/include/boost/type_traits/integral_constant.hpp
Line
Count
Source
1
//  (C) Copyright John Maddock 2015. 
2
//  Use, modification and distribution are subject to the 
3
//  Boost Software License, Version 1.0. (See accompanying file 
4
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6
#ifndef BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP
7
#define BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP
8
9
#include <boost/config.hpp>
10
#include <boost/detail/workaround.hpp>
11
12
#if (BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
13
   || BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x610)) \
14
   || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \
15
   || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \
16
   || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) )\
17
   || defined(BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE)
18
19
20
namespace boost{
21
   namespace mpl
22
   {
23
      template <bool B> struct bool_;
24
      template <class I, I val> struct integral_c;
25
      struct integral_c_tag;
26
   }
27
}
28
29
#else
30
31
namespace mpl_{
32
33
   template <bool B> struct bool_;
34
   template <class I, I val> struct integral_c;
35
   struct integral_c_tag;
36
}
37
38
namespace boost
39
{
40
   namespace mpl
41
   {
42
      using ::mpl_::bool_;
43
      using ::mpl_::integral_c;
44
      using ::mpl_::integral_c_tag;
45
   }
46
}
47
48
#endif
49
50
namespace boost{
51
52
   template <class T, T val>
53
   struct integral_constant
54
   {
55
      typedef mpl::integral_c_tag tag;
56
      typedef T value_type;
57
      typedef integral_constant<T, val> type;
58
      static const T value = val;
59
60
      operator const mpl::integral_c<T, val>& ()const
61
      {
62
         static const char data[sizeof(long)] = { 0 };
63
         static const void* pdata = data;
64
         return *(reinterpret_cast<const mpl::integral_c<T, val>*>(pdata));
65
      }
66
      BOOST_CONSTEXPR operator T()const { return val; }
67
   };
68
69
   template <class T, T val>
70
   T const integral_constant<T, val>::value;
71
      
72
   template <bool val>
73
   struct integral_constant<bool, val>
74
   {
75
      typedef mpl::integral_c_tag tag;
76
      typedef bool value_type;
77
      typedef integral_constant<bool, val> type;
78
      static const bool value = val;
79
80
      operator const mpl::bool_<val>& ()const
81
120
      {
82
120
         static const char data[sizeof(long)] = { 0 };
83
120
         static const void* pdata = data;
84
120
         return *(reinterpret_cast<const mpl::bool_<val>*>(pdata));
85
120
      }
86
      BOOST_CONSTEXPR operator bool()const { return val; }
87
   };
88
89
   template <bool val>
90
   bool const integral_constant<bool, val>::value;
91
92
   typedef integral_constant<bool, true> true_type;
93
   typedef integral_constant<bool, false> false_type;
94
95
}
96
97
#endif